home *** CD-ROM | disk | FTP | other *** search
Text File | 1992-08-19 | 67.7 KB | 2,686 lines |
- Newsgroups: comp.lang.c++
- Path: sparky!uunet!stanford.edu!ames!pacbell.com!tlhouns
- From: tlhouns@srv.PacBell.COM (Lee Hounshell)
- Subject: VAR - a string class library (source)
- Message-ID: <1992Aug20.012612.18347@PacBell.COM>
- Sender: news@PacBell.COM (Pacific Bell Netnews)
- Organization: Pacific * Bell
- Date: Thu, 20 Aug 1992 01:26:12 GMT
- Lines: 2675
-
-
- 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
-
- enjoy.
-
- -Lee
-
-
-
- #-----------------------------------cut here----------------------------------
-
- # This is a shell archive. Remove anything before this line,
- # then unpack it by saving it in a file and typing "sh file".
- #
- # Wrapped by photon!tlhouns on Wed Aug 19 18:18:18 PDT 1992
- # Contents: README LEGAL_NOTICE var.3++ Makefile var.H var.C Misc.H Misc.C
- # demo.C
-
- echo x - README
- sed 's/^@//' > "README" <<'@//E*O*F README//'
-
- 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!
- "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
- @//E*O*F README//
- chmod u=rw,g=r,o=r README
-
- echo x - LEGAL_NOTICE
- sed 's/^@//' > "LEGAL_NOTICE" <<'@//E*O*F LEGAL_NOTICE//'
-
- Any use of this source code must include, in the user documentation
- and internal comments to the code, and notices to the end user as
- follows:
-
- Copyright (c) 1992 Lee Hounshell
-
- LEE HOUNSHELL MAKES NO REPRESENTATIONS ABOUT THE SUITABILITY OF
- THIS SOURCE CODE FOR ANY PURPOSE. IT IS PROVIDED "AS IS"
- WITHOUT EXPRESS OR IMPLIED WARRANTY OF ANY KIND. LEE HOUNSHELL
- SEVERALLY AND INDIVIDUALLY, DISCLAIM ALL WARRANTIES WITH REGARD
- TO THIS SOURCE CODE, INCLUDING ALL IMPLIED WARRANTIES OF
- MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. IN NO
- EVENT SHALL LEE HOUNSHELL BE LIABLE FOR ANY SPECIAL, INDIRECT,
- INCIDENTAL, OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER
- RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
- OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
- OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOURCE CODE.
-
- Permission to use, copy, modify, and distribute this software
- and its documentation for any purpose and without fee is hereby
- granted, provided that the above copyright notice appear in all
- copies and that both that copyright notice and this permission
- notice appear in supporting documentation, and that the name of
- Lee Hounshell not be used in advertising in publicity pertaining
- to distribution of the software without specific, written prior
- permission.
-
- @//E*O*F LEGAL_NOTICE//
- chmod u=rw,g=r,o=r LEGAL_NOTICE
-
- echo x - var.3++
- sed 's/^@//' > "var.3++" <<'@//E*O*F var.3++//'
- @.po 6
- @.TH VAR 3++ "1/92" "Version 1.0" "Variable Base Type String Class Library"
-
- @.SH CLASS
- VAR \- Variable Base Type String Class Library
- @.SH SYNOPSIS
- @.B #include <var.H>
- @.PP
- @.nf
- @.ta.5i 1.0i 4.0i
- \fB
- class var {
-
- public:
- // Constructors & Destructors
- var(void); // constructor
- var(const varsize &); // constructor
- var(const char *); // constructor
- var(const char); // constructor
- var(const short); // constructor
- var(const unsigned short); // constructor
- var(const int); // constructor
- var(const unsigned int); // constructor
- var(const long); // constructor
- var(const unsigned long); // constructor
- var(const double); // constructor
- var(const var &); // copy constructor
- ~var(void); // destructor
-
- // Operators
- var & operator = (const char *); // assignment
- var & operator = (const var &); // assignment
- char & operator [] (const int); // indexing
- subvar & operator () (int, int) const; // substring
- subvar & operator () (const int) const; // substring
- friend ostream & operator << (ostream &, const var &); // output
- friend istream & operator >> (istream &, var &); // input
- friend class subvar; // substring
-
- // More Operators (used for arithmetic type extension)
- var & operator = (const char); // assignment
- var & operator = (const short); // assignment
- var & operator = (const unsigned short); // assignment
- var & operator = (const int); // assignment
- var & operator = (const unsigned int); // assignment
- var & operator = (const long); // assignment
- var & operator = (const unsigned long); // assignment
- var & operator = (const double); // assignment
-
- // Casting Operators
- operator char * (void) const; // type conversion
- operator double (void) const; // type conversion
-
- // Assignment Operators
- var & operator ++ (void); // increment (pre-index only)
- var & operator -- (void); // decrement (pre-index only)
- var operator ! (void) const; // not
-
- var operator + (const var &) const; // addition OR concatenation
- var operator - (const var &) const; // subtraction
- var operator * (const var &) const; // multiplication
- var operator / (const var &) const; // division
- var operator % (const var &) const; // remainder
-
- var & operator += (const var &); // addition OR concatenation
- var & operator -= (const var &); // subtraction
- var & operator *= (const var &); // multiplication
- var & operator /= (const var &); // division
- var & operator %= (const var &); // remainder
-
- var & operator += (const char &); // addition OR concatenation
- var & operator += (const char *); // addition OR concatenation
- var & operator -= (const char *); // subtraction
- var & operator *= (const char *); // multiplication
- var & operator /= (const char *); // division
- var & operator %= (const char *); // remainder
-
- var & operator += (const double); // addition OR concatenation
- var & operator -= (const double); // subtraction
- var & operator *= (const double); // multiplication
- var & operator /= (const double); // division
- var & operator %= (const double); // remainder
-
- friend var operator + (const char *, const var &); // addition OR concatenation
- friend var operator - (const char *, const var &); // subtraction
- friend var operator * (const char *, const var &); // multiplication
- friend var operator / (const char *, const var &); // division
- friend var operator % (const char *, const var &); // remainder
- friend var operator + (const var &, const char *); // addition OR concatenation
- friend var operator - (const var &, const char *); // subtraction
- friend var operator * (const var &, const char *); // multiplication
- friend var operator / (const var &, const char *); // division
- friend var operator % (const var &, const char *); // remainder
-
- friend var operator + (const var &, const double); // addition OR concatenation
- friend var operator - (const var &, const double); // subtraction
- friend var operator * (const var &, const double); // multiplication
- friend var operator / (const var &, const double); // division
- friend var operator % (const var &, const double); // remainder
- friend var operator + (const double, const var &); // addition OR concatenation
- friend var operator - (const double, const var &); // subtraction
- friend var operator * (const double, const var &); // multiplication
- friend var operator / (const double, const var &); // division
- friend var operator % (const double, const var &); // remainder
-
- // Equality Operators
- int operator == (const var &) const; // equality
- int operator != (const var &) const; // inequality
- int operator < (const var &) const; // less than
- int operator > (const var &) const; // greater than
- int operator <= (const var &) const; // less than or equal
- int operator >= (const var &) const; // greater than or equal
-
- friend int operator == (const var &, const char *); // equality
- friend int operator != (const var &, const char *); // inequality
- friend int operator < (const var &, const char *); // less than
- friend int operator > (const var &, const char *); // greater than
- friend int operator <= (const var &, const char *); // less than or equal
- friend int operator >= (const var &, const char *); // greater than or equal
- friend int operator == (const char *, const var &); // equality
- friend int operator != (const char *, const var &); // inequality
- friend int operator < (const char *, const var &); // less than
- friend int operator > (const char *, const var &); // greater than
- friend int operator <= (const char *, const var &); // less than or equal
- friend int operator >= (const char *, const var &); // greater than or equal
-
- friend int operator == (const var &, const double); // equality
- friend int operator != (const var &, const double); // inequality
- friend int operator < (const var &, const double); // less than
- friend int operator > (const var &, const double); // greater than
- friend int operator <= (const var &, const double); // less than or equal
- friend int operator >= (const var &, const double); // greater than or equal
- friend int operator == (const double, const var &); // equality
- friend int operator != (const double, const var &); // inequality
- friend int operator < (const double, const var &); // less than
- friend int operator > (const double, const var &); // greater than
- friend int operator <= (const double, const var &); // less than or equal
- friend int operator >= (const double, const var &); // greater than or equal
-
- // Custom Interface
- void null(int); // "null" out string
- void changesize(int); // change allocated memory
- int length(void) const; // length of string
- const char * vartype(void) const; // name of this var type
- void change_type(const char *); // change var type
- int is_string(void) const; // test var type
- int is_double(void) const; // test var type
- int is_long(void) const; // test var type
- int strchr(const char) const; // strchr(char) index
- int strrchr(const char) const; // strrchr(char) index
- var & concat(const var &); // concatenation
- var & format(const char *); // set output format
- };
- @.fi
- \fP
-
- @.SH DESCRIPTION
- Class \fBvar\fP represents a \fBstring\fP object class that also provides all
- the traditional functionality of the C base types: char, int, long, float, double, and char*.
- \fBVar\fP, is in many ways a "super-string" class.
- The var class does a pretty good job of offering a base data "container" object that can either
- assume its "type" at run time, based on context or remain a "fixed" type, always.
-
- @.SS var will do
- @.TP 2
- +
- all the base data types (eg: short, int, long, char *, float, double ...)
- @.TP 2
- +
- string types
- @.TP 2
- +
- arithmetic
- @.TP 2
- +
- strings and operations on strings
- @.TP 2
- +
- sub-strings and operations on sub-strings
- @.TP 2
- +
- intelligent "mixing" of operations between mixed types
- @.TP 2
- +
- formatted output using the stream library
-
- @.SH PUBLIC CONSTRUCTORS
- @.SS var(void);
- This constructor is used to declare an "untyped" var object. Type is determined
- at run-time, based on context of use.
-
- @.SS var(const varsize &);
- This constructor is used to declare an "string" var object, with preallocated memory.
- The object's type can change at run-time, based on context.
-
- @.SS var(const char *);
- This constructor is used to declare a "string" object initialize from a "char *".
- The object's type can change at run-time, based on context.
-
- @.SS var(const char);
- This constructor is used to declare an "numeric" var object, initialized from a char.
- The object's type can change at run-time, based on context.
-
- @.SS var(const short);
- This constructor is used to declare an "numeric" var object, initialized from a short.
- The object's type is fixed and will not change at run-time.
-
- @.SS var(const unsigned short);
- This constructor is used to declare an "numeric" var object, initialized from an unsigned short.
- The object's type is fixed and will not change at run-time.
-
- @.SS var(const int);
- This constructor is used to declare an "numeric" var object, initialized from an int.
- The object's type is fixed and will not change at run-time.
-
- @.SS var(const unsigned int);
- This constructor is used to declare an "numeric" var object, initialized from an unsigned int.
- The object's type is fixed and will not change at run-time.
-
- @.SS var(const long);
- This constructor is used to declare an "numeric" var object, initialized from a long.
- The object's type is fixed and will not change at run-time.
-
- @.SS var(const unsigned long);
- This constructor is used to declare an "numeric" var object, initialized from an unsigned long.
- The object's type is fixed and will not change at run-time.
-
- @.SS var(const double);
- This constructor is used to declare an "numeric" var object, initialized from a double or float.
- The object's type is fixed and will not change at run-time.
-
- @.SS var(const var &);
- This constructor is used to declare a var object, which is a copy of another var.
- The object assumes the characteristics of the initializing object.
-
- @.SS ~var(void);
- The destructor returns all memory allocated by the object back to the OS.
-
-
- @.SH PUBLIC OPERATORS
- @.SS Arithmetic and Concatenation Operators
- Most operators (+, -, /, *, %, +=, etc..) will operate as expected.
- The "+" and "+=" operators will either do addition or concatenation, as appropriate.
- if concatenation is required, then the \fB"var.concat(var)"\fP member function should
- be used.
-
- @.SS Relational Operators
- These also operate as expected. If "string" objects are compared, the comparison
- will be as performed by \fBstrcmp(3)\fP.
-
- @.SS The Indexing Operator []
- You can index a character from inside a \fBvar\fP by using
- the \fB"char & operator [] (const int);"\fP operator.
- A reference to the character is returned, which can be assigned to.
- Do not assign the NULL character using this operator.
- Instead call the member function \fB"null(index)"\fP.
-
- @.SS Sub-strings
- Two operators are provide for substring operation. The
- first, \fB"subvar & operator () (int start, int length) const;"\fP
- will extract a string starting at "start" for "length" characters.
- The second, \fB"subvar & operator () (const int start) const;"\fP will
- extract a string starting at "start" to the end of the string.
-
- @.SS Type Casting
- Only two type casts are required by \fBvar\fP. The first converts
- the object into a "char *". The second converts the object into a
- double. Implicit conversion between "char *" and "double" types
- will be performed by your C++ compiler.
-
- @.SS Formatted Input/Output
- You can usr \fBvar\fP with the io stream library. Object can be
- both output and input using the ">>" and "<<" operators.
- For formatted output, be sure to set the object's "format template"
- prior to calling the ">>" operator. (see \fB"var & format(const char *);"\fP)
-
- @.SH PUBLIC MEMBER FUNCTIONS
-
- @.SS Truncating a string
- The \fB"void null(int index);"\fP function will truncate a \fBvar\fP
- object, starting from the specified index postion.
-
- @.SS Memory Allocation
- The \fB"void changesize(int newsize);"\fP can be used to increase
- allocated memory for a var. Memory can NOT be decreased. Allocated
- memory is returned to the heap when an object goes out of scope.
-
- @.SS Determining Var's Length
- The \fB"int length(void) const;"\fP function returns the "size" of a \fBvar\fP.
-
- @.SS Determining Var's Type
- The \fB"const char * vartype(void) const;"\fP function returns the "type" of a \fBvar\fP.
- Possible types are: "VAR_STRING", "VAR_LONG" and "VAR_DOUBLE".
-
- @.SS Explititly Changing a Var's Type
- The \fB"void change_type(const char *newtype);"\fP function can be used
- to set an exact type. Valid values for "newtype" are "string", "short",
- "unsigned short", "int", "unsigned int", "long", "unsigned long",
- "float", and "double".
-
- @.SS Testing a Var's Type
- Three functions are provided that allow testing a \fBvar\fP type.
- They are as follows: \fB"int is_string(void) const;"\fP,
- \fB"int is_double(void) const;"\fP, and \fB"int is_long(void) const;"\fP
-
- @.SS Searching for a Character
- Two functions are provided that search a \fBvar\fP for a specified
- character. Both return an offset. The first \fB"int strchr(const char) const;"\fP
- searches forward. The second, \fB"int strrchr(const char) const;"\fP
- searches backward.
-
- @.SS Concatenation
- Concatenation can be forced, regardless of type with the \fB"var & concat(const var &);"\fP
- function.
-
- @.SS Setting the Output Format
- The \fB"var & format(const char *fmt);"\fP function will allow you to specify an
- output format. This format will remain in effect until changed. Printf()
- style output formats can be introduced anywhere in the format statment.
- Multiple formateed output directives can appear in the same "fmt". Each
- directive will receive a copy of the object. Automatic type conversion will
- occur.
-
-
- @.SH AUTHOR
- Lee Hounshell - 1/92
-
- @.SH EXAMPLE
- @.nf
- #include <stdlib.h>
- #include <stream.h>
- #include <var.H>
-
- main ()
- {
- var value; // declare an "untyped" var
- value = "hello world"; // initialize it
- cout << value << endl; // output "hello world"
- value = value(3, value.length() - 6); // substring example
- cout << value << endl; // output "lo wo"
- value = 35; // assignment of int
- value += 42.375; // add 42.375 to present value
- cout << value << endl; // output "77.375"
- cout << value.format("formatted output example %05d of value") << endl;
- cout << value.format("multiple outputs #1=%d, #2=%9.2f of value") << endl;
- value.null(2); // truncate string
- value += " sunset strip"; // concatenate a string
- cout << value.format("%s") << endl; // output "77 sunset strip"
- cout << value[3] << value[4] << value[5] << endl; // output "sun"
- }
- @.fi
-
- @.SH SUPERCLASSES
- none.
-
- @.SH SUBCLASSES
- none
-
- @.SH BUGS
- Assignment of an array of vars to another array of vars
- must currently be done one elemnt at a time.
-
- @//E*O*F var.3++//
- chmod u=rw,g=r,o=r var.3++
-
- echo x - Makefile
- sed 's/^@//' > "Makefile" <<'@//E*O*F Makefile//'
- ############################################################################
- # make - compiles the C++ library (libvar.a)
- # make clean - removes all .o files generated in these procedures
- # make clobber - removes all libraries, cleans up .o's
- ############################################################################
-
-
- # from the two below, pick the operating system closest to yours:
- INCDIRS = -I.
-
- SYS = SUN
- CC = CC
- CFLAGS = -O $(INCDIRS)
- ARFLAGS = rv
-
-
- is_bsd = test $(SYS) = SUN
-
- all: libvar.a
-
- C++FILES = var.C Misc.C
- INS_HFILES = var.H Misc.H
- HFILES = $(INS_HFILES)
-
- OBJECTS = ${C++FILES:.C=.o}
-
- libvar.a: $(OBJECTS)
- ar $(ARFLAGS) $@ $?
- if $(is_bsd) ; then ranlib $@; fi
-
- $(OBJECTS): $(HFILES)
-
-
- clean:
- rm -f *.o a.out core $(OBJECTS)
- cd demo; $(MAKE) clean
-
- clobber: clean
- rm -fr $(DOTAS)
- cd demo; $(MAKE) clobber
-
- #####
- #####
- #.SUFFIXES: .o .C .C~ .c .c~
- @.SUFFIXES: .o .C .C~
- @.C~.C:
- -cd $(<D); $(GET) $(GFLAGS) $(<F)
- @.C.c:
- $(CC) $(CFLAGS) -Fc $*.C > $*.c
- @.C.o:
- $(CC) $(CFLAGS) -c $*.C
- @.C~.o:
- -cd $(<D); $(GET) $(GFLAGS) $(<F)
- $(CC) $(CFLAGS) -c $*.C
-
- @//E*O*F Makefile//
- chmod u=rw,g=r,o=r Makefile
-
- echo x - var.H
- sed 's/^@//' > "var.H" <<'@//E*O*F var.H//'
- //
- // NAME: var.H
- //
- // PURPOSE: C++ Generic "Universal Variable" Class Library Header File
- // AUTHOR: Lee Hounshell
- //
-
- #ifndef VAR_H
- #define VAR_H
-
- #include "string.h"
-
- // -----------------------------------------------------------------------------
- //
- class varsize {
- // dummy class needed for var constructor of specific size that
- // doesn't conflict with the var integer type constructor
- public:
- // Constructors & Destructors
- varsize(int sz); // constructor
- int size; // size of var
- };
-
- class subvar;
-
- // -----------------------------------------------------------------------------
- //
- class var {
-
- public:
- // Standard Interface
- const var & type(void) const; // who am i
-
- // Constructors & Destructors
- var(void); // constructor
- var(const varsize &); // constructor
- var(const char *); // constructor
- var(const char); // constructor
- var(const short); // constructor
- var(const unsigned short); // constructor
- var(const int); // constructor
- var(const unsigned int); // constructor
- var(const long); // constructor
- var(const unsigned long); // constructor
- var(const double); // constructor
- var(const var &); // copy constructor
- ~var(void); // destructor
-
- // Operators
- var & operator = (const char *); // assignment
- var & operator = (const var &); // assignment
- char & operator [] (const int); // indexing
- subvar & operator () (int, int) const; // substring
- subvar & operator () (const int) const; // substring
- friend ostream & operator << (ostream &, const var &); // output
- friend istream & operator >> (istream &, var &); // input
- friend class subvar; // substring
-
- // More Operators (used for arithmetic type extension)
- var & operator = (const char); // assignment
- var & operator = (const short); // assignment
- var & operator = (const unsigned short); // assignment
- var & operator = (const int); // assignment
- var & operator = (const unsigned int); // assignment
- var & operator = (const long); // assignment
- var & operator = (const unsigned long); // assignment
- var & operator = (const double); // assignment
-
- // Casting Operators
- operator char * (void) const; // type conversion
- operator double (void) const; // type conversion
-
- // Assignment Operators
- var & operator ++ (void); // increment (pre-index only)
- var & operator -- (void); // decrement (pre-index only)
- var operator ! (void) const; // not
-
- var operator + (const var &) const; // addition OR concatenation
- var operator - (const var &) const; // subtraction
- var operator * (const var &) const; // multiplication
- var operator / (const var &) const; // division
- var operator % (const var &) const; // remainder
-
- var & operator += (const var &); // addition OR concatenation
- var & operator -= (const var &); // subtraction
- var & operator *= (const var &); // multiplication
- var & operator /= (const var &); // division
- var & operator %= (const var &); // remainder
-
- var & operator += (const char &); // addition OR concatenation
- var & operator += (const char *); // addition OR concatenation
- var & operator -= (const char *); // subtraction
- var & operator *= (const char *); // multiplication
- var & operator /= (const char *); // division
- var & operator %= (const char *); // remainder
-
- var & operator += (const double); // addition OR concatenation
- var & operator -= (const double); // subtraction
- var & operator *= (const double); // multiplication
- var & operator /= (const double); // division
- var & operator %= (const double); // remainder
-
- friend var operator + (const char *, const var &); // addition OR concatenation
- friend var operator - (const char *, const var &); // subtraction
- friend var operator * (const char *, const var &); // multiplication
- friend var operator / (const char *, const var &); // division
- friend var operator % (const char *, const var &); // remainder
- friend var operator + (const var &, const char *); // addition OR concatenation
- friend var operator - (const var &, const char *); // subtraction
- friend var operator * (const var &, const char *); // multiplication
- friend var operator / (const var &, const char *); // division
- friend var operator % (const var &, const char *); // remainder
-
- friend var operator + (const var &, const double); // addition OR concatenation
- friend var operator - (const var &, const double); // subtraction
- friend var operator * (const var &, const double); // multiplication
- friend var operator / (const var &, const double); // division
- friend var operator % (const var &, const double); // remainder
- friend var operator + (const double, const var &); // addition OR concatenation
- friend var operator - (const double, const var &); // subtraction
- friend var operator * (const double, const var &); // multiplication
- friend var operator / (const double, const var &); // division
- friend var operator % (const double, const var &); // remainder
-
- // Equality Operators
- int operator == (const var &) const; // equality
- int operator != (const var &) const; // inequality
- int operator < (const var &) const; // less than
- int operator > (const var &) const; // greater than
- int operator <= (const var &) const; // less than or equal
- int operator >= (const var &) const; // greater than or equal
-
- friend int operator == (const var &, const char *); // equality
- friend int operator != (const var &, const char *); // inequality
- friend int operator < (const var &, const char *); // less than
- friend int operator > (const var &, const char *); // greater than
- friend int operator <= (const var &, const char *); // less than or equal
- friend int operator >= (const var &, const char *); // greater than or equal
- friend int operator == (const char *, const var &); // equality
- friend int operator != (const char *, const var &); // inequality
- friend int operator < (const char *, const var &); // less than
- friend int operator > (const char *, const var &); // greater than
- friend int operator <= (const char *, const var &); // less than or equal
- friend int operator >= (const char *, const var &); // greater than or equal
-
- friend int operator == (const var &, const double); // equality
- friend int operator != (const var &, const double); // inequality
- friend int operator < (const var &, const double); // less than
- friend int operator > (const var &, const double); // greater than
- friend int operator <= (const var &, const double); // less than or equal
- friend int operator >= (const var &, const double); // greater than or equal
- friend int operator == (const double, const var &); // equality
- friend int operator != (const double, const var &); // inequality
- friend int operator < (const double, const var &); // less than
- friend int operator > (const double, const var &); // greater than
- friend int operator <= (const double, const var &); // less than or equal
- friend int operator >= (const double, const var &); // greater than or equal
-
- // Custom Interface
- void null(int); // "null" out string
- void changesize(int); // change allocated memory
- int length(void) const; // length of string
- const char * vartype(void) const; // name of this var type
- void change_type(const char *); // change var type
- int is_string(void) const; // test var type
- int is_double(void) const; // test var type
- int is_long(void) const; // test var type
- int strchr(const char) const; // strchr(char) index
- int strrchr(const char) const; // strrchr(char) index
- var & concat(const var &); // concatenation
- var & format(const char *); // set output format
- void print(ostream &) const; // output
- void read(istream &); // input
-
- static int save_me; // cntrl object input
- static int save_it(const int save_flag = var::save_me); // input ctrl
-
- protected:
-
- private:
- int numcheck(const char *) const; // determine is_numeric value
-
- static const var ctype; // for type() function
- short fixed; // 1=fixed data type
- short is_numeric; // 0=string, 1=short/int/long, 2=float/double
- int data_str_len; // length of allocated "string"
- int data_str_end; // index to current "end" of string
- char *data_str; // for "string" data
- char *format_str; // the input/output format string
-
- };
-
-
- class subvar : public var {
- public:
- var & operator = (const var &); // substring replacement
- var *varptr;
- unsigned offset;
- unsigned length;
- };
-
- #endif
-
- @//E*O*F var.H//
- chmod u=rw,g=r,o=r var.H
-
- echo x - var.C
- sed 's/^@//' > "var.C" <<'@//E*O*F var.C//'
- //
- // NAME: var.C
- //
- // PURPOSE: C++ Generic "Universal Variable" library class
- // AUTHOR: Lee Hounshell
- //
-
- #include <stddef.h>
- #include <stream.h>
- #include <stdlib.h>
- #include <ctype.h>
- #include <string.h>
- #include "var.H"
- #include "Misc.H"
-
- const int VAR_PAD_SIZE = 128;
- const int VAR_DEF_SIZE = 16;
-
- const short VAR_STRING = 0;
- const short VAR_LONG = 1;
- const short VAR_DOUBLE = 2;
-
- char * DEFAULT_STRING_FORMAT = "'%s'";
- char * DEFAULT_INT_FORMAT = "%d";
- char * DEFAULT_UINT_FORMAT = "%u";
- char * DEFAULT_LONG_FORMAT = "%ld";
- char * DEFAULT_ULONG_FORMAT = "%lu";
- char * DEFAULT_DOUBLE_FORMAT = "%9.2f";
-
- // -----------------------------------------------------------------------------
-
- const var var::ctype = "var";
- int var::save_me = 1;
-
-
- const var & var::type(void) const
- {
- return var::ctype;
- }
-
-
- varsize::varsize(int sz)
- {
- size = sz;
- }
-
-
- var::var(void)
- {
- fixed = 0;
- is_numeric = VAR_STRING;
- data_str_len = VAR_DEF_SIZE;
- data_str_end = 0;
- data_str = new char[data_str_len];
- data_str[0] = 0;
- format_str = DEFAULT_STRING_FORMAT;
- }
-
-
- var::var(const char *str)
- {
- fixed = 1;
- is_numeric = VAR_STRING;
- data_str_end = strlen(str);
- data_str_len = data_str_end + VAR_DEF_SIZE;
- data_str = new char[data_str_len];
- strcpy(data_str, str);
- format_str = DEFAULT_STRING_FORMAT;
- }
-
-
- var::var(const varsize &vsz)
- {
- fixed = 0;
- is_numeric = VAR_STRING;
- data_str_len = vsz.size + VAR_DEF_SIZE;
- data_str_end = 0;
- data_str = new char[data_str_len];
- data_str[0] = 0;
- format_str = DEFAULT_STRING_FORMAT;
- }
-
-
- var::var(const char ch)
- {
- fixed = 0;
- is_numeric = VAR_STRING;
- data_str_len = VAR_DEF_SIZE;
- data_str_end = 1;
- data_str = new char[data_str_len];
- data_str[0] = ch;
- data_str[1] = 0;
- format_str = DEFAULT_STRING_FORMAT;
- }
-
-
- var::var(const short int_num)
- {
- fixed = 1;
- is_numeric = VAR_LONG;
- data_str_len = VAR_DEF_SIZE;
- data_str = new char[data_str_len];
- strcpy(data_str, itoa(int_num));
- data_str_end = strlen(data_str);
- format_str = DEFAULT_INT_FORMAT;
- }
-
-
- var::var(const unsigned short int_num)
- {
- fixed = 1;
- is_numeric = VAR_LONG;
- data_str_len = VAR_DEF_SIZE;
- data_str = new char[data_str_len];
- strcpy(data_str, itoa(int_num));
- data_str_end = strlen(data_str);
- format_str = DEFAULT_UINT_FORMAT;
- }
-
-
- var::var(const int int_num)
- {
- fixed = 1;
- is_numeric = VAR_LONG;
- data_str_len = VAR_DEF_SIZE;
- data_str = new char[data_str_len];
- strcpy(data_str, itoa(int_num));
- data_str_end = strlen(data_str);
- format_str = DEFAULT_INT_FORMAT;
- }
-
-
- var::var(const unsigned int int_num)
- {
- fixed = 1;
- is_numeric = VAR_LONG;
- data_str_len = VAR_DEF_SIZE;
- data_str = new char[data_str_len];
- strcpy(data_str, itoa(int_num));
- data_str_end = strlen(data_str);
- format_str = DEFAULT_UINT_FORMAT;
- }
-
-
- var::var(const long long_num)
- {
- fixed = 1;
- is_numeric = VAR_LONG;
- data_str_len = VAR_DEF_SIZE;
- data_str = new char[data_str_len];
- strcpy(data_str, ltoa(long_num));
- data_str_end = strlen(data_str);
- format_str = DEFAULT_LONG_FORMAT;
- }
-
-
- var::var(const unsigned long long_num)
- {
- fixed = 1;
- is_numeric = VAR_LONG;
- data_str_len = VAR_DEF_SIZE;
- data_str = new char[data_str_len];
- strcpy(data_str, ltoa(long_num));
- data_str_end = strlen(data_str);
- format_str = DEFAULT_ULONG_FORMAT;
- }
-
-
- var::var(const double double_num)
- {
- fixed = 1;
- is_numeric = VAR_DOUBLE;
- data_str_len = VAR_DEF_SIZE;
- data_str = new char[data_str_len];
- strcpy(data_str, dtoa(double_num));
- data_str_end = strlen(data_str);
- format_str = DEFAULT_DOUBLE_FORMAT;
- }
-
-
- var::var(const var &v)
- {
- fixed = v.fixed;
- is_numeric = v.is_numeric;
- if (v.data_str && v.data_str_end) {
- data_str_len = v.data_str_end + VAR_DEF_SIZE;
- data_str_end = v.data_str_end;
- data_str = new char[data_str_len];
- strcpy(data_str, v.data_str);
- }
- else {
- data_str_len = VAR_DEF_SIZE;
- data_str_end = 0;
- data_str = new char[data_str_len];
- data_str[0] = 0;
- }
- format_str = DEFAULT_STRING_FORMAT;
- }
-
-
- var::~var(void)
- {
- if (data_str) {
- delete data_str;
- }
- if (format_str
- && format_str != DEFAULT_STRING_FORMAT
- && format_str != DEFAULT_INT_FORMAT
- && format_str != DEFAULT_UINT_FORMAT
- && format_str != DEFAULT_LONG_FORMAT
- && format_str != DEFAULT_ULONG_FORMAT
- && format_str != DEFAULT_DOUBLE_FORMAT) {
- delete format_str;
- }
- }
-
- // -----------------------------------------------------------------------------
-
- var & var::operator = (const char *str)
- {
- if (fixed && is_numeric) {
- if (is_numeric == VAR_DOUBLE) {
- double d = atod((char *) str);
- *this = d;
- }
- else {
- long l = atol(str);
- *this = l;
- }
- }
- else {
- int len = strlen(str) + 1;
- if (data_str_len < len) {
- delete data_str;
- data_str_len = len;
- data_str = new char[data_str_len];
- }
- data_str_end = len - 1;
- strcpy(data_str, str);
- if (!fixed) {
- int str_is_numeric = numcheck(data_str);
- is_numeric = str_is_numeric;
- }
- }
- return *this;
- }
-
-
- var & var::operator = (const var &l)
- {
- if (this != &l) {
- if (data_str_len <= l.data_str_end) {
- delete data_str;
- data_str_len = l.data_str_end + VAR_DEF_SIZE;
- data_str = new char[data_str_len];
- }
- data_str_end = l.data_str_end;
- strncpy(data_str, l.data_str, l.data_str_end);
- data_str[data_str_end] = 0;
- if (!fixed) {
- is_numeric = numcheck(data_str);
- }
- //
- // Note: the output "format" of a var variable is preserved
- //
- }
- return *this;
- }
-
-
- char & var::operator [] (const int index)
- {
- static char error_ch;
- if (index < 0) {
- cerr << "ERROR: " << " - var[" << index << "] negative index used." << endl;
- error_ch = 0;
- return error_ch;
- }
- if (data_str_len <= index) {
- // this is technically a program error, but I'll be nice and extend the string's length
- data_str_len = index + VAR_PAD_SIZE;
- data_str_end = index + 1;
- char *buf = new char[data_str_len];
- sprintf(buf, "%-*.*s", data_str_end, data_str_end, data_str);
- delete data_str;
- data_str = buf;
- data_str[index] = 0;
- cerr << "WARNING: " << " - var index '" << index << "' beyond current string boundary." << endl;
- }
- while (data_str_end < index) {
- data_str[data_str_end++] = ' '; // pad to index with spaces if necessary
- }
- if (data_str_end == index) {
- data_str[data_str_end] = 0; // the end of a string is ALWAYS 0
- if ((data_str_end + 1) < data_str_len) {
- data_str[++data_str_end] = 0; // the new end of string is also 0
- }
- }
- return data_str[index];
- }
-
-
- // for substrings
- subvar & var::operator () (const int offset) const
- {
- return operator () (offset, -1);
- }
-
-
- // for substrings
- subvar & var::operator () (int offset, int length) const
- {
- static subvar _esi_subvar;
- if (length < 0) {
- length = data_str_end - offset;
- }
- char *substr = new char[length + 1];
- strncpy(substr, data_str + offset, (int) length);
- substr[length] = 0;
- _esi_subvar.var::operator = (substr);
- _esi_subvar.varptr = (var *) this;
- _esi_subvar.offset = offset;
- _esi_subvar.length = length;
- delete substr;
- return _esi_subvar;
- }
-
-
- // for syntax: var(offset, length) = var
- var & subvar::operator = (const var &substr)
- {
- char *srcstr = varptr->data_str;
- char *repstr = substr.data_str;
- int replen = length;
- if (substr.data_str_end < length) {
- replen = substr.data_str_end;
- }
- int len = varptr->data_str_len;
- char *newstr = new char[len];
- strncpy(newstr, srcstr, offset); // data from string being replaced up to "offset"
- if (replen) {
- strncpy(newstr + offset, repstr, replen); // replacement string data
- }
- int newoffset = offset + replen;
- if (newoffset < varptr->data_str_end) {
- strcpy(newstr + newoffset, srcstr + offset + length);
- }
- else {
- newstr[newoffset] = 0;
- }
- if (varptr->data_str) {
- delete varptr->data_str;
- }
- varptr->data_str = newstr;
- varptr->data_str_len = len;
- varptr->data_str_end = strlen(newstr);
- if (!varptr->fixed) {
- varptr->is_numeric = numcheck(newstr);
- }
- return *varptr;
- }
-
- // -----------------------------------------------------------------------------
-
- var & var::operator = (const char ch)
- {
- char buf[2];
- buf[0] = ch;
- buf[1] = 0;
- *this = buf;
- return *this;
- }
-
-
- var & var::operator = (const short int_num)
- {
- char *str = itoa(int_num);
- int len = strlen(str);
- if (data_str_len < len) {
- delete data_str;
- data_str_len = len + 1;
- data_str = new char[data_str_len];
- }
- data_str_end = len;
- strcpy(data_str, str);
- if (!fixed) {
- is_numeric = VAR_LONG;
- }
- return *this;
- }
-
-
- var & var::operator = (const unsigned short int_num)
- {
- char *str = itoa(int_num);
- int len = strlen(str);
- if (data_str_len < len) {
- delete data_str;
- data_str_len = len + 1;
- data_str = new char[data_str_len];
- }
- data_str_end = len;
- strcpy(data_str, str);
- is_numeric = VAR_LONG;
- return *this;
- }
-
-
- var & var::operator = (const int int_num)
- {
- char *str = itoa(int_num);
- int len = strlen(str);
- if (data_str_len < len) {
- delete data_str;
- data_str_len = len + 1;
- data_str = new char[data_str_len];
- }
- data_str_end = len;
- strcpy(data_str, str);
- if (!fixed) {
- is_numeric = VAR_LONG;
- }
- return *this;
- }
-
-
- var & var::operator = (const unsigned int int_num)
- {
- char *str = itoa(int_num);
- int len = strlen(str);
- if (data_str_len < len) {
- delete data_str;
- data_str_len = len + 1;
- data_str = new char[data_str_len];
- }
- data_str_end = len;
- strcpy(data_str, str);
- if (!fixed) {
- is_numeric = VAR_LONG;
- }
- return *this;
- }
-
-
- var & var::operator = (const long long_num)
- {
- char *str = ltoa(long_num);
- int len = strlen(str);
- if (data_str_len < len) {
- delete data_str;
- data_str_len = len + 1;
- data_str = new char[data_str_len];
- }
- data_str_end = len;
- strcpy(data_str, str);
- if (!fixed) {
- is_numeric = VAR_LONG;
- }
- return *this;
- }
-
-
- var & var::operator = (const unsigned long long_num)
- {
- char *str = ltoa(long_num);
- int len = strlen(str);
- if (data_str_len < len) {
- delete data_str;
- data_str_len = len + 1;
- data_str = new char[data_str_len];
- }
- data_str_end = len;
- strcpy(data_str, str);
- if (!fixed) {
- is_numeric = VAR_LONG;
- }
- return *this;
- }
-
-
- var & var::operator = (const double dbl_num)
- {
- char *str = dtoa(dbl_num);
- int len = strlen(str);
- if (data_str_len < len) {
- delete data_str;
- data_str_len = len + 1;
- data_str = new char[data_str_len];
- }
- data_str_end = len;
- strcpy(data_str, str);
- if (!fixed) {
- is_numeric = VAR_DOUBLE;
- }
- return *this;
- }
-
- // -----------------------------------------------------------------------------
-
- var::operator char * (void) const
- {
- return data_str;
- }
-
-
- var::operator double (void) const
- {
- return atod(data_str);
- }
-
- // -----------------------------------------------------------------------------
-
- var & var::operator ++ (void) // increment (pre-index only)
- {
- *this += 1;
- return *this;
- }
-
-
- var & var::operator -- (void) // decrement (pre-index only)
- {
- *this -= 1;
- return *this;
- }
-
-
- var var::operator ! (void) const // not
- {
- var not(1);
- if ((int) *this) {
- not = 0;
- }
- return not;
- }
-
- // -----------------------------------------------------------------------------
-
- var var::operator + (const var & v) const // addition OR concatenation
- {
- var add;
- if (is_numeric && v.is_numeric) {
- // do math in the highest precision specified
- int n_type = (is_numeric > v.is_numeric) ? is_numeric : v.is_numeric;
- switch (n_type) {
- case VAR_LONG:
- add = (long) *this + (long) v;
- break;
- default:
- // should be VAR_DOUBLE
- add = (double) *this + (double) v;
- break;
- }
- }
- else {
- // concatenate strings
- delete add.data_str;
- add.data_str_len = data_str_end + v.data_str_end + VAR_PAD_SIZE;
- add.data_str_end = data_str_end + v.data_str_end;
- add.data_str = new char[add.data_str_len];
- strcpy(add.data_str, data_str);
- strcpy((add.data_str) + data_str_end, v.data_str);
- add.is_numeric = VAR_STRING;
- }
- return add;
- }
-
-
- var var::operator - (const var & v) const // subtraction
- {
- var sub;
- // do math in the highest precision specified
- int n_type = (is_numeric > v.is_numeric) ? is_numeric : v.is_numeric;
- switch (n_type) {
- case VAR_LONG:
- sub = (long) *this - (long) v;
- sub.is_numeric = VAR_LONG;
- break;
- default:
- // should be VAR_DOUBLE
- sub = (double) *this - (double) v;
- break;
- }
- return sub;
- }
-
-
- var var::operator * (const var & v) const // multiplication
- {
- var times;
- // do math in the highest precision specified
- int n_type = (is_numeric > v.is_numeric) ? is_numeric : v.is_numeric;
- switch (n_type) {
- case VAR_LONG:
- times = (long) *this * (long) v;
- break;
- default:
- // should be VAR_DOUBLE
- times = (double) *this * (double) v;
- break;
- }
- return times;
- }
-
-
- var var::operator / (const var & v) const // division
- {
- var div;
- // do math in the highest precision specified
- int n_type = (is_numeric > v.is_numeric) ? is_numeric : v.is_numeric;
- switch (n_type) {
- case VAR_LONG:
- div = (long) *this / (long) v;
- break;
- default:
- // should be VAR_DOUBLE
- div = (double) *this / (double) v;
- break;
- }
- return div;
- }
-
-
- var var::operator % (const var & v) const // remainder
- {
- var mod;
- // do math in the highest precision specified
- int n_type = (is_numeric > v.is_numeric) ? is_numeric : v.is_numeric;
- switch (n_type) {
- case VAR_LONG:
- mod = (long) *this % (long) v;
- break;
- default:
- // should be VAR_DOUBLE
- // really, I shouldn't allow this..
- mod = (double) ((long) *this % (long) v);
- break;
- }
- return mod;
- }
-
- // -----------------------------------------------------------------------------
-
- var & var::operator += (const var & v)
- {
- if ((is_numeric == VAR_STRING) || (v.is_numeric == VAR_STRING)) {
- concat(v);
- }
- else {
- *this = (*this) + v;
- }
- return *this;
- }
-
-
- var & var::operator -= (const var & v)
- {
- *this = (*this) - v;
- return *this;
- }
-
-
- var & var::operator *= (const var & v)
- {
- *this = (*this) * v;
- return *this;
- }
-
-
- var & var::operator /= (const var & v)
- {
- *this = (*this) / v;
- return *this;
- }
-
-
- var & var::operator %= (const var & v)
- {
- *this = (*this) % v;
- return *this;
- }
-
- // -----------------------------------------------------------------------------
-
- var & var::operator += (const char & ch)
- {
- var foo = ch;
- *this += foo;
- return *this;
- }
-
- var & var::operator += (const char * v)
- {
- var foo = v;
- *this += foo;
- return *this;
- }
-
-
- var & var::operator -= (const char * v)
- {
- var foo = v;
- *this -= foo;
- return *this;
- }
-
-
- var & var::operator *= (const char * v)
- {
- var foo = v;
- *this *= foo;
- return *this;
- }
-
-
- var & var::operator /= (const char * v)
- {
- var foo = v;
- *this /= foo;
- return *this;
- }
-
-
- var & var::operator %= (const char * v)
- {
- var foo = v;
- *this %= foo;
- return *this;
- }
-
- // -----------------------------------------------------------------------------
-
- var & var::operator += (const double v)
- {
- var foo = v;
- *this += foo;
- return *this;
- }
-
-
- var & var::operator -= (const double v)
- {
- var foo = v;
- *this -= foo;
- return *this;
- }
-
-
- var & var::operator *= (const double v)
- {
- var foo = v;
- *this *= foo;
- return *this;
- }
-
-
- var & var::operator /= (const double v)
- {
- var foo = v;
- *this /= foo;
- return *this;
- }
-
-
- var & var::operator %= (const double v)
- {
- var foo = v;
- *this %= foo;
- return *this;
- }
-
- // -----------------------------------------------------------------------------
-
- var operator + (const char * s, const var & v)
- {
- var foo = s;
- return foo + v;
- }
-
-
- var operator - (const char * s, const var & v)
- {
- var foo = s;
- return foo - v;
- }
-
-
- var operator * (const char * s, const var & v)
- {
- var foo = s;
- return foo * v;
- }
-
-
- var operator / (const char * s, const var & v)
- {
- var foo = s;
- return foo / v;
- }
-
-
- var operator % (const char * s, const var & v)
- {
- var foo = s;
- return foo % v;
- }
-
-
- var operator + (const var & v, const char * s)
- {
- var foo = s;
- return v + foo;
- }
-
-
- var operator - (const var & v, const char * s)
- {
- var foo = s;
- return v - foo;
- }
-
-
- var operator * (const var & v, const char * s)
- {
- var foo = s;
- return v * foo;
- }
-
-
- var operator / (const var & v, const char * s)
- {
- var foo = s;
- return v / foo;
- }
-
-
- var operator % (const var & v, const char * s)
- {
- var foo = s;
- return v % foo;
- }
-
- // -----------------------------------------------------------------------------
-
- var operator + (const var & v, const double d)
- {
- var foo = d;
- return v + foo;
- }
-
-
- var operator - (const var & v, const double d)
- {
- var foo = d;
- return v - foo;
- }
-
-
- var operator * (const var & v, const double d)
- {
- var foo = d;
- return v * foo;
- }
-
-
- var operator / (const var & v, const double d)
- {
- var foo = d;
- return v / foo;
- }
-
-
- var operator % (const var & v, const double d)
- {
- var foo = d;
- return v % foo;
- }
-
-
- var operator + (const double d, const var & v)
- {
- var foo = d;
- return foo + v;
- }
-
-
- var operator - (const double d, const var & v)
- {
- var foo = d;
- return foo - v;
- }
-
-
- var operator * (const double d, const var & v)
- {
- var foo = d;
- return foo * v;
- }
-
-
- var operator / (const double d, const var & v)
- {
- var foo = d;
- return foo / v;
- }
-
-
- var operator % (const double d, const var & v)
- {
- var foo = d;
- return foo % v;
- }
-
- // -----------------------------------------------------------------------------
-
- int var::operator == (const var & t) const // equality
- {
- if (is_numeric && t.is_numeric) {
- if (is_numeric == VAR_LONG && t.is_numeric == VAR_LONG) {
- return (long) (*this) == (long) t;
- }
- return (double) (*this) == (double) t;
- }
- else {
- if (data_str_end && t.data_str_end) {
- return !strcmp(data_str, t.data_str);
- }
- else {
- return data_str_end == t.data_str_end;
- }
- }
- }
-
-
- int var::operator != (const var & t) const // inequality
- {
- if (is_numeric && t.is_numeric) {
- if (is_numeric == VAR_LONG && t.is_numeric == VAR_LONG) {
- return (long) (*this) != (long) t;
- }
- return (double) (*this) != (double) t;
- }
- else {
- if (data_str_end && t.data_str_end) {
- return strcmp(data_str, t.data_str);
- }
- else {
- return data_str_end != t.data_str_end;
- }
- }
- }
-
-
- int var::operator < (const var & t) const // less than
- {
- if (is_numeric && t.is_numeric) {
- if (is_numeric == VAR_LONG && t.is_numeric == VAR_LONG) {
- return (long) (*this) < (long) t;
- }
- return (double) (*this) < (double) t;
- }
- else {
- if (data_str_end && t.data_str_end) {
- return (strcmp(data_str, t.data_str) < 0);
- }
- else {
- return data_str_end < t.data_str_end;
- }
- }
- }
-
-
- int var::operator > (const var & t) const // greater than
- {
- if (is_numeric && t.is_numeric) {
- if (is_numeric == VAR_LONG && t.is_numeric == VAR_LONG) {
- return (long) (*this) > (long) t;
- }
- return (double) (*this) > (double) t;
- }
- else {
- if (data_str_end && t.data_str_end) {
- return (strcmp(data_str, t.data_str) > 0);
- }
- else {
- return data_str_end > t.data_str_end;
- }
- }
- }
-
-
- int var::operator <= (const var & t) const // less than or equal
- {
- if (is_numeric && t.is_numeric) {
- if (is_numeric == VAR_LONG && t.is_numeric == VAR_LONG) {
- return (long) (*this) <= (long) t;
- }
- return (double) (*this) <= (double) t;
- }
- else {
- if (data_str_end && t.data_str_end) {
- return (strcmp(data_str, t.data_str) <= 0);
- }
- else {
- return data_str_end <= t.data_str_end;
- }
- }
- }
-
-
- int var::operator >= (const var & t) const // greater than or equal
- {
- if (is_numeric && t.is_numeric) {
- if (is_numeric == VAR_LONG && t.is_numeric == VAR_LONG) {
- return (long) (*this) >= (long) t;
- }
- return (double) (*this) >= (double) t;
- }
- else {
- if (data_str_end && t.data_str_end) {
- return (strcmp(data_str, t.data_str) >= 0);
- }
- else {
- return data_str_end >= t.data_str_end;
- }
- }
- }
-
- // -----------------------------------------------------------------------------
-
- int operator == (const var & t, const char * s)
- {
- var foo = s;
- return t == foo;
- }
-
-
- int operator != (const var & t, const char * s)
- {
- var foo = s;
- return t != foo;
- }
-
-
- int operator < (const var & t, const char * s)
- {
- var foo = s;
- return t < foo;
- }
-
-
- int operator > (const var & t, const char * s)
- {
- var foo = s;
- return t > foo;
- }
-
-
- int operator <= (const var & t, const char * s)
- {
- var foo = s;
- return t <= foo;
- }
-
-
- int operator >= (const var & t, const char * s)
- {
- var foo = s;
- return t >= foo;
- }
-
-
- int operator == (const char * s, const var & t)
- {
- var foo = s;
- return foo == t;
- }
-
-
- int operator != (const char * s, const var & t)
- {
- var foo = s;
- return foo != t;
- }
-
-
- int operator < (const char * s, const var & t)
- {
- var foo = s;
- return foo < t;
- }
-
-
- int operator > (const char * s, const var & t)
- {
- var foo = s;
- return foo > t;
- }
-
-
- int operator <= (const char * s, const var & t)
- {
- var foo = s;
- return foo <= t;
- }
-
-
- int operator >= (const char * s, const var & t)
- {
- var foo = s;
- return foo >= t;
- }
-
- // -----------------------------------------------------------------------------
-
- int operator == (const var & t, const double d)
- {
- return (double) t == d;
- }
-
-
- int operator != (const var & t, const double d)
- {
- return (double) t != d;
- }
-
-
- int operator < (const var & t, const double d)
- {
- return (double) t < d;
- }
-
-
- int operator > (const var & t, const double d)
- {
- return (double) t > d;
- }
-
-
- int operator <= (const var & t, const double d)
- {
- return (double) t <= d;
- }
-
-
- int operator >= (const var & t, const double d)
- {
- return (double) t >= d;
- }
-
-
- int operator == (const double d, const var & t)
- {
- return d == (double) t;
- }
-
-
- int operator != (const double d, const var & t)
- {
- return d != (double) t;
- }
-
-
- int operator < (const double d, const var & t)
- {
- return d < (double) t;
- }
-
-
- int operator > (const double d, const var & t)
- {
- return d > (double) t;
- }
-
-
- int operator <= (const double d, const var & t)
- {
- return d <= (double) t;
- }
-
-
- int operator >= (const double d, const var & t)
- {
- return d >= (double) t;
- }
-
- // -----------------------------------------------------------------------------
-
- void var::null(int index)
- {
- if (index >= data_str_len) {
- cerr << "WARNING: " << " - var::null(" << index << ") - the index out of range." << endl;
- (*this)[index] = 0;
- data_str_end = index;
- }
- else {
- data_str[index] = 0;
- data_str_end = index;
- }
- }
-
-
- void var::changesize(int newsize)
- {
- if (newsize > data_str_len) {
- char *buf = new char[newsize];
- if (data_str) {
- strncpy(buf, data_str, data_str_end);
- buf[data_str_end] = 0;
- delete data_str;
- }
- else {
- *buf = 0;
- data_str_end = 0;
- }
- data_str_len = newsize;
- data_str = buf;
- }
- }
-
-
- int var::length(void) const
- {
- return data_str_end;
- }
-
-
- const char * var::vartype(void) const
- {
- switch (is_numeric) {
- case VAR_STRING:
- return "VAR_STRING";
- case VAR_LONG:
- return "VAR_LONG";
- case VAR_DOUBLE:
- return "VAR_DOUBLE";
- }
- return "var type unknown";
- }
-
-
- void var::change_type(const char *ntype)
- {
- if (ntype == NULL) {
- return;
- }
- int index = strlen(ntype);
- if (!index) {
- return;
- }
- char *new_type = new char[index + 1];
- if (ntype[0] == '(' && ntype[index - 1] == ')') {
- strcpy(new_type, &ntype[1]);
- index = strlen(new_type) - 1;
- if (index <= 0) {
- delete new_type;
- return;
- }
- new_type[index] = 0; // drop parens
- }
- else {
- strcpy(new_type, ntype);
- }
- if (new_type[index - 1] == ' ') {
- new_type[index - 1] = 0;
- }
- fixed = 1;
- if (!strcmp(new_type, "var")) {
- is_numeric = numcheck((const char *) *this);
- }
- else if (!strcmp(new_type, "string")) {
- is_numeric = VAR_STRING;
- }
- else if (!strcmp(new_type, "short")) {
- is_numeric = VAR_LONG;
- }
- else if (!strcmp(new_type, "unsigned short")) {
- is_numeric = VAR_LONG;
- }
- else if (!strcmp(new_type, "int")) {
- is_numeric = VAR_LONG;
- }
- else if (!strcmp(new_type, "unsigned int")) {
- is_numeric = VAR_LONG;
- }
- else if (!strcmp(new_type, "long")) {
- is_numeric = VAR_LONG;
- }
- else if (!strcmp(new_type, "unsigned long")) {
- is_numeric = VAR_LONG;
- }
- else if (!strcmp(new_type, "float")) {
- is_numeric = VAR_DOUBLE;
- }
- else if (!strcmp(new_type, "double")) {
- is_numeric = VAR_DOUBLE;
- }
- else {
- cerr << "WARNING: " << " - change_type(" << new_type << ") - unrecognized type name." << endl;
- }
- delete new_type;
- }
-
-
- int var::is_string(void) const
- {
- return is_numeric == VAR_STRING;
- }
-
-
- int var::is_double(void) const
- {
- return is_numeric == VAR_DOUBLE;
- }
-
-
- int var::is_long(void) const
- {
- return is_numeric == VAR_LONG;
- }
-
-
- int var::strchr(const char ch) const
- {
- for (int i = 0; i < data_str_end; ++i) {
- if (data_str[i] == ch) {
- return i;
- }
- }
- return -1;
- }
-
-
- int var::strrchr(const char ch) const
- {
- for (int i = data_str_end - 1; i >= 0; --i) {
- if (data_str[i] == ch) {
- return i;
- }
- }
- return -1;
- }
-
-
- var & var::concat(const var & str)
- {
- // concatenate strings
- int new_data_str_end = data_str_end + str.data_str_end;
- if (new_data_str_end >= data_str_len) {
- var add;
- add.data_str_len = data_str_len + str.data_str_len + VAR_PAD_SIZE;
- add.data_str_end = new_data_str_end;
- add.data_str = new char[add.data_str_len];
- strcpy(add.data_str, data_str);
- strcpy((add.data_str) + data_str_end, str.data_str);
- *this = add;
- }
- else {
- strcpy(data_str + data_str_end, str.data_str);
- data_str_end += str.data_str_end;
- }
- return *this;
- }
-
-
- var & var::format(const char * fmt)
- {
- if (format_str
- && format_str != DEFAULT_STRING_FORMAT
- && format_str != DEFAULT_INT_FORMAT
- && format_str != DEFAULT_UINT_FORMAT
- && format_str != DEFAULT_LONG_FORMAT
- && format_str != DEFAULT_ULONG_FORMAT
- && format_str != DEFAULT_DOUBLE_FORMAT) {
- delete format_str;
- }
- if (fmt) {
- format_str = new char[strlen(fmt) + 1];
- strcpy(format_str, fmt);
- }
- else {
- format_str = NULL;
- }
- return *this;
- }
-
-
- int var::numcheck(const char * str) const
- {
- if (!str || !*str) {
- return VAR_STRING; // assume a string
- }
- char *ptr = (char *) str;
- int nc = VAR_LONG; // assume a signed long
- int decimal_yet = 0;
- if (*ptr == '.' && *(ptr + 1)) {
- nc = VAR_DOUBLE; // floating point number
- decimal_yet = 1;
- ++ptr;
- }
- else if (*ptr == '-' && *(ptr + 1)) {
- // skip optional sign char
- ++ptr;
- }
- while (*ptr) {
- if (*ptr == '.' && !decimal_yet) {
- decimal_yet = 1;
- nc = VAR_DOUBLE; // assume a double
- }
- else if (!isdigit(*ptr)) {
- return VAR_STRING; // nope.. got a string
- }
- ++ptr;
- }
- return nc;
- }
-
- // -----------------------------------------------------------------------------
-
- int var::save_it(const int save_flag)
- {
- int s = var::save_me;
- var::save_me = save_flag;
- return s;
- }
-
- // -----------------------------------------------------------------------------
-
- ostream & operator << (ostream &out, const var &d)
- {
- d.print(out);
- return out;
- }
-
-
- void var::print(ostream &out) const
- {
- // NOTE: the "read()" function requires a newline to appear after the last quote.
- // I assume that this newline was appropriately output by the var class user.
- if (!format_str || (format_str && *format_str == 0)) {
- out << "var OBJECT: {"
- << Inc << "fixed = " << fixed
- << Tab << "is_numeric = " << is_numeric
- << Tab << "data_str_len = " << data_str_len
- << Tab << "data_str_end = " << data_str_end
- << Tab << "data_str = '" << data_str << "'"
- << Tab << "format_str = '" << format_str << "'"
- << Dec << "}" << endl;
- }
- else {
- // we need to use the specified format string for output
- int len = length() + 1;
- char *outbuf = new char[2048];
- char *fptr = format_str;
- while (*fptr) {
- if (*fptr != '%' && *fptr != '\\') {
- out << *fptr;
- ++fptr;
- }
- else if (*fptr == '\\') {
- switch (*(fptr + 1)) {
- case 'n':
- cout << '\n';
- break;
- case 't':
- cout << '\t';
- break;
- case 'v':
- cout << '\v';
- break;
- case 'b':
- cout << '\b';
- break;
- case 'r':
- cout << '\r';
- break;
- case 'f':
- cout << '\f';
- break;
- case 'a':
- cout << '\007';
- break;
- case '\\':
- cout << '\\';
- break;
- case '?':
- cout << '\?';
- break;
- case '\'':
- cout << '\'';
- break;
- case '\"':
- cout << '\"';
- break;
- default:
- cout << *(fptr + 1);
- }
- fptr += 2;
- }
- else {
- // Hmmm.. we need to do some special formatting
- // first extract this printf-style format string
- char smallfmtstr[128];
- char *smptr = smallfmtstr;
- *smptr = 0;
- if (*(fptr + 1) == '%') {
- strcpy(outbuf, "%");
- fptr += 2;
- }
- else {
- while (*fptr) {
- *smptr = *fptr++;
- *(smptr + 1) = 0;
- // integer
- if (*smptr == 'd') {
- sprintf(outbuf, smallfmtstr, (int) *this);
- break;
- }
- // unsigned integer
- if (*smptr == 'o' || *smptr == 'u' || *smptr == 'x' || *smptr == 'X') {
- sprintf(outbuf, smallfmtstr, (unsigned int) *this);
- break;
- }
- // float or double
- if (*smptr == 'f' || *smptr == 'e' || *smptr == 'E' || *smptr == 'g' || *smptr == 'G') {
- sprintf(outbuf, smallfmtstr, (double) *this);
- break;
- }
- // character
- if (*smptr == 'c') {
- if (!strcmp(vartype(), "VAR_STRING")) {
- const char *tmp = (const char *) (*this);
- sprintf(outbuf, smallfmtstr, tmp[0]);
- }
- else {
- sprintf(outbuf, smallfmtstr, (char) ((int) *this));
- }
- break;
- }
- // string
- if (*smptr == 's') {
- sprintf(outbuf, smallfmtstr, (const char *) *this);
- break;
- }
- ++smptr;
- }
- }
- out << outbuf;
- }
- }
- out << flush;
- delete outbuf;
- }
- }
-
-
- istream & operator >> (istream &in, var &d)
- {
- d.read(in);
- return in;
- }
-
-
- void var::read(istream &in)
- {
- // input the same format as was created by the output operator
- char buf1[4096];
- char buf2[4096];
- if (!format_str || (format_str && *format_str == 0)) {
- look_for(in, '{');
- look_for(in, '=');
- in >> fixed;
- look_for(in, '=');
- in >> is_numeric;
- look_for(in, '=');
- in >> data_str_len;
- look_for(in, '=');
- in >> data_str_end;
- look_for(in, '=');
- scan_string(in, buf1, sizeof(buf1));
- look_for(in, '=');
- scan_string(in, buf2, sizeof(buf2));
- look_for(in, '}');
- *this = buf1;
- format(buf2);
- }
- else {
- // LEE: need to add input/output formatting capabilities
- }
- }
-
- @//E*O*F var.C//
- chmod u=rw,g=r,o=r var.C
-
- echo x - Misc.H
- sed 's/^@//' > "Misc.H" <<'@//E*O*F Misc.H//'
- //
- // NAME: MISC.H
- //
- // PURPOSE: generalized functions for C++ class library routines
- // AUTHOR: Lee Hounshell
- //
-
- #ifndef MISC_H
- #define MISC_H
-
- #include <stream.h>
-
- char *itoa(const int foo);
- char *uitoa(const unsigned int foo);
-
- #ifdef HP
- char *ltoa(long foo);
- char *ultoa(unsigned long foo);
- #else
- char *ltoa(const long foo);
- char *ultoa(const unsigned long foo);
- #endif
-
- char *dtoa(const double foo);
- double atod(char * foo);
- char *ltoTime(const long date24);
- istream & look_for(istream &in, char c);
- void scan_string(istream &in, char *ptr, int size);
- ostream & Tab(ostream &out);
- ostream & Inc(ostream &out);
- ostream & Dec(ostream &out);
-
- #endif
-
- @//E*O*F Misc.H//
- chmod u=rw,g=r,o=r Misc.H
-
- echo x - Misc.C
- sed 's/^@//' > "Misc.C" <<'@//E*O*F Misc.C//'
- //
- // NAME: MISC.C
- //
- // PURPOSE: generalized functions for C++ class library routines
- // AUTHOR: Lee Hounshell
- //
-
- #include <stdlib.h>
- #include <stream.h>
- #include <memory.h>
- #include <string.h>
- #include <ctype.h>
- #include "Misc.H"
-
-
- // =============================================================================
- // stuff thet jes' be here 'cause i wuz be 2 lazy 2 done drop it sumplace else, Mazza!
- // =============================================================================
-
-
- // -----------------------------------------------------------------------------
- // convert an integer into an ascii string. return a pointer to that string.
- //
- char *itoa(const int foo)
- {
- static char int_buf[28];
- sprintf(int_buf, "%d", foo);
- return int_buf;
- }
-
-
- // convert an unsigned integer into an ascii string. return a pointer to that string.
- //
- char *uitoa(const unsigned int foo)
- {
- static char int_buf[28];
- sprintf(int_buf, "%u", foo);
- return int_buf;
- }
-
-
- // convert a long into an ascii string. return a pointer to that string.
- //
- #ifdef HP
- char *ltoa(long foo)
- #else
- char *ltoa(const long foo)
- #endif
- {
- static char long_buf[28];
- sprintf(long_buf, "%ld", foo);
- return long_buf;
- }
-
-
- // convert an unsigned long into an ascii string. return a pointer to that string.
- //
- #ifdef HP
- char *ultoa(unsigned long foo)
- #else
- char *ultoa(const unsigned long foo)
- #endif
- {
- static char long_buf[28];
- sprintf(long_buf, "%lu", foo);
- return long_buf;
- }
-
-
- // convert a double into an ascii string. return a pointer to that string.
- // truncate any extra zeros after the decimal point.
- //
- char *dtoa(const double foo)
- {
- static char double_buf[28];
- sprintf(double_buf, "%lf", foo);
- char *ptr;
- for (ptr = double_buf; *ptr; ++ptr) {
- if (*ptr == '.') {
- // we may need to truncate zeroes
- ptr = double_buf + (strlen(double_buf) - 1);
- while (*ptr == '0') {
- *ptr-- = 0;
- }
- if (*ptr == '.') {
- *ptr = 0;
- }
- break;
- }
- }
- return double_buf;
- }
-
-
- // convert an ascii string to a double
- //
- double atod(char * foo)
- {
- double d = 0;
- if (!foo || !*foo) {
- return d;
- }
- if (!isdigit(*foo)) {
- if (*foo != '-' && *foo != '+') {
- return d;
- }
- if (!isdigit(*(foo + 1))) {
- return d;
- }
- }
- sscanf(foo, "%lf", &d);
- return d;
- }
-
- // -----------------------------------------------------------------------------
-
- // convert a 24-hour time (hhmm) into LMOS string format (hhmmZ - where Z is 'A' or 'P')
- //
- char *ltoTime(const long date24)
- {
- static char time_buf[6];
- *time_buf = 0;
- if (date24 != 0L) {
- long minute = date24 % 100;
- long hour = (date24 - minute) / 100;
- char ampm = 'A';
- if (hour >= 12) {
- ampm = 'P';
- if (hour > 12) hour -= 12;
- }
- sprintf(time_buf, "%02d%02d%c", hour, minute, ampm);
- return time_buf;
- }
- }
-
-
- // -----------------------------------------------------------------------------
- // scan input until the desired character is found
- //
- istream & look_for(istream &in, char c)
- {
- int input = 0;
- if (getenv("INPUT_DEBUG") != NULL) {
- cerr << "Debug: looking for input character '" << c << "'" << endl;
- }
- while (input != c && input != EOF) {
- input = in.get();
- if (getenv("INPUT_DEBUG") != NULL) {
- cerr << input;
- }
- }
- return in;
- }
-
-
- // -----------------------------------------------------------------------------
- // this function is used by lots of other classes for I/O, also.
- // it really is a sort of "general-purpose," non-class-specific routine
- // i use it for extracting class memebers from a saved object
- //
- void scan_string(istream &in, char *ptr, int size)
- {
- char buffer[3];
- char *input;
- if (size) --size;
- if (getenv("INPUT_DEBUG") != NULL) {
- cerr << "Debug: scanning for string (length=" << size << ")" << endl;
- }
- if (ptr != NULL) {
- input = ptr;
- }
- else {
- input = buffer;
- }
- *input = 0;
- look_for(in, '\''); // find first quote
- int endflag = 0;
- int count = 0;
- while (1) {
- int ch;
- if ((ch = in.get()) == EOF) {
- if (getenv("INPUT_DEBUG") != NULL) {
- cerr << "debug: scan_string(): unexpected EOF found" << endl;
- }
- *input = 0;
- break;
- }
- *input = ch;
- if (getenv("INPUT_DEBUG") != NULL) {
- cerr << *input;
- }
- if (*input == '\n' && endflag) { // all done!
- *input = 0;
- if (getenv("INPUT_DEBUG") != NULL) {
- cerr << "\nDebug: scan_string() found: '" << ptr << "'" << endl;
- }
- break; // found end of string
- }
- if (count >= size) { // string is too big for buffer
- if (getenv("INPUT_DEBUG") != NULL) {
- cerr << "\nDebug: scan_string() size exceeded - truncating string" << endl;
- }
- if (ch != '\'') {
- look_for(in, '\''); // skip to last quote
- }
- endflag = 1;
- continue;
- }
- if (ptr != NULL && endflag) { // possibly found end of string
- *(input+1) = *input;
- *input = '\'';
- ++input;
- ++count;
- }
- if ((endflag = (*input == '\'')) == 0) {// got a close quote??
- if (*ptr) ++input;
- ++count;
- }
- }
- }
-
-
- // these functions are also used by other classes for I/O.
- // they keep track of "indent" levels for printing objects with inheritance
-
- static int no_tab_stops = 0;
-
-
- // -----------------------------------------------------------------------------
- //
- ostream & Tab(ostream &out)
- {
- out << "\n";
- for (int i = 0; i < no_tab_stops; ++i) {
- out << " "; // really one-half a tab stop
- }
- return out;
- }
-
-
- // -----------------------------------------------------------------------------
- //
- ostream & Inc(ostream &out)
- {
- ++no_tab_stops;
- return Tab(out);
- }
-
-
- // -----------------------------------------------------------------------------
- //
- ostream & Dec(ostream &out)
- {
- --no_tab_stops;
- return Tab(out);
- }
-
- @//E*O*F Misc.C//
- chmod u=rw,g=r,o=r Misc.C
-
- echo x - demo.C
- sed 's/^@//' > "demo.C" <<'@//E*O*F demo.C//'
- #include <stdlib.h>
- #include <stream.h>
- #include <var.H>
-
- main ()
- {
- var value; // declare an "untyped" var
- value = "hello world"; // initialize it
- cout << value << endl; // output "hello world"
- value = value(3, value.length() - 6); // substring example
- cout << value << endl; // output "lo wo"
- value = 35; // assignment of int
- value += 42.375; // add 42.375 to present value
- cout << value << endl; // output "77.375"
- cout << value.format("formatted output example %05d of value") << endl;
- cout << value.format("multiple outputs #1=%d, #2=%9.2f of value") << endl;
- value.null(2); // truncate string
- value += " sunset strip"; // concatenate a string
- cout << value.format("%s") << endl; // output "77 sunset strip"
- cout << value[3] << value[4] << value[5] << endl; // output "sun"
- }
-
- @//E*O*F demo.C//
- chmod u=rw,g=r,o=r demo.C
-
- exit 0
- --
- Lee Hounshell - (510) 823-2432
- tlhouns@srv.pacbell.com
- Alchemical Engineer and Virtual Realist
-