home *** CD-ROM | disk | FTP | other *** search
/ Source Code 1994 March / Source_Code_CD-ROM_Walnut_Creek_March_1994.iso / compsrcs / misc / volume31 / var / part01 < prev    next >
Encoding:
Text File  |  1992-08-21  |  53.9 KB  |  2,125 lines

  1. Newsgroups: comp.sources.misc
  2. From: tlhouns@srv.pacbell.com (Lee Hounshell)
  3. Subject:  v31i091:  var - a C++ string class library, Part01/02
  4. Message-ID: <csm-v31i091=var.104945@sparky.IMD.Sterling.COM>
  5. X-Md4-Signature: c06ffbe54ada717d84c18d0bb446b631
  6. Date: Fri, 21 Aug 1992 15:50:16 GMT
  7. Approved: kent@sparky.imd.sterling.com
  8.  
  9. Submitted-by: tlhouns@srv.pacbell.com (Lee Hounshell)
  10. Posting-number: Volume 31, Issue 91
  11. Archive-name: var/part01
  12. Environment: C++
  13.  
  14. This is "var", a C++ object library that is kinda like a "super-string" class.
  15. The var class does a pretty good job of offering a data object that assumes
  16. its "type" at run time, based on context of use.  Rarely will you need to
  17. declare int's, or longs, or doubles or char[] or even string objects again!
  18. "Var" does it all (or at least tries to).
  19.  
  20.         + var will do base data types (eg: int, long, char *, float, string ...)        + var will do arithmetic
  21.         + var will do strings and operations on strings
  22.         + var will do sub-strings and operations on sub-strings
  23.         + var will intelligently "mix" operations between mixed types
  24.         + var will do formatted output using the stream library
  25.         + individual vars can be "staticly" typed, or they can assume
  26.           type at runtime, based on context.
  27.  
  28. To use this class, simply type make and a library file "libvar.a" will be
  29. created.  This class has been used extensively here at Pacific Bell as a
  30. base class in development of our own internal C++ class libraries. I've
  31. even used "var" as the YYSTYPE type inside yacc/lex programs!!
  32.  
  33. If there is sufficient interest in "var" I may post a few other "base" C++
  34. classes that I've developed.. such as an "associative array" class that uses
  35. a "var" to index another "var."
  36.  
  37. If you like (or dislike) var, please drop me a line.
  38. Mail bug reports and comments to:
  39. tlhouns@srv.pacbell.com
  40.  
  41.  -Lee
  42. -------
  43. #! /bin/sh
  44. # This is a shell archive.  Remove anything before this line, then feed it
  45. # into a shell via "sh file" or similar.  To overwrite existing files,
  46. # type "sh file -c".
  47. # The tool that generated this appeared in the comp.sources.unix newsgroup;
  48. # send mail to comp-sources-unix@uunet.uu.net if you want that tool.
  49. # Contents:  README LEGAL_NOTICE var.3++ var.C
  50. # Wrapped by kent@sparky on Fri Aug 21 10:47:44 1992
  51. PATH=/bin:/usr/bin:/usr/ucb ; export PATH
  52. echo If this archive is complete, you will see the following message:
  53. echo '          "shar: End of archive 1 (of 2)."'
  54. if test -f 'README' -a "${1}" != "-c" ; then 
  55.   echo shar: Will not clobber existing file \"'README'\"
  56. else
  57.   echo shar: Extracting \"'README'\" \(1356 characters\)
  58.   sed "s/^X//" >'README' <<'END_OF_FILE'
  59. X
  60. XThis is "var", a C++ object library that is kinda like a "super-string" class.
  61. XThe var class does a pretty good job of offering a data object that assumes
  62. Xits "type" at run time, based on context of use.  Rarely will you need to
  63. Xdeclare int's, or longs, or doubles or char[] or even string objects!
  64. X"Var" does it all (or at least tries to).
  65. X
  66. X    + var will do base data types (eg: int, long, char *, float, string ...)
  67. X    + var will do arithmetic
  68. X    + var will do strings and operations on strings
  69. X    + var will do sub-strings and operations on sub-strings
  70. X    + var will intelligently "mix" operations between mixed types
  71. X    + var will do formatted output using the stream library
  72. X    + individual vars can be "staticly" typed, or they can assume
  73. X      type at runtime, based on context.
  74. X
  75. XTo use this class, simply type make and a library file "libvar.a" will be
  76. Xcreated.  This class has been used extensively here at Pacific Bell as a
  77. Xbase class in development of our own internal C++ class libraries. I've
  78. Xeven used "var" as the YYSTYPE type inside yacc/lex programs!!
  79. X
  80. XIf there is sufficient interest in "var" I may post a few other "base" C++
  81. Xclasses that I've developed.. such as an "associative array" class that uses
  82. Xa "var" to index another "var."
  83. X
  84. XIf you like (or dislike) var, please drop me a line.
  85. XMail bug reports and comments to:
  86. Xtlhouns@srv.pacbell.com
  87. X
  88. X-Lee
  89. END_OF_FILE
  90.   if test 1356 -ne `wc -c <'README'`; then
  91.     echo shar: \"'README'\" unpacked with wrong size!
  92.   fi
  93.   # end of 'README'
  94. fi
  95. if test -f 'LEGAL_NOTICE' -a "${1}" != "-c" ; then 
  96.   echo shar: Will not clobber existing file \"'LEGAL_NOTICE'\"
  97. else
  98.   echo shar: Extracting \"'LEGAL_NOTICE'\" \(1388 characters\)
  99.   sed "s/^X//" >'LEGAL_NOTICE' <<'END_OF_FILE'
  100. X
  101. X        Any use of this source code must include, in the user documentation
  102. X        and internal comments to the code, and notices to the end user as
  103. X        follows:
  104. X
  105. X    Copyright (c) 1992 Lee Hounshell
  106. X    LEE HOUNSHELL MAKES NO REPRESENTATIONS ABOUT THE SUITABILITY OF
  107. X        THIS SOURCE CODE FOR ANY PURPOSE. IT IS PROVIDED "AS IS"
  108. X        WITHOUT EXPRESS OR IMPLIED WARRANTY OF ANY KIND.  LEE HOUNSHELL
  109. X    SEVERALLY AND INDIVIDUALLY, DISCLAIM ALL WARRANTIES WITH REGARD
  110. X    TO THIS SOURCE CODE, INCLUDING ALL IMPLIED WARRANTIES OF
  111. X    MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. IN NO
  112. X    EVENT SHALL LEE HOUNSHELL BE LIABLE FOR ANY SPECIAL, INDIRECT,
  113. X    INCIDENTAL, OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER
  114. X    RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
  115. X    OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
  116. X    OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOURCE CODE.
  117. X
  118. X    Permission to use, copy, modify, and distribute this software
  119. X    and its documentation for any purpose and without fee is hereby
  120. X    granted, provided that the above copyright notice appear in all
  121. X    copies and that both that copyright notice and this permission
  122. X    notice appear in supporting documentation, and that the name of
  123. X    Lee Hounshell not be used in advertising in publicity pertaining
  124. X    to distribution of the software without specific, written prior
  125. X    permission.
  126. X
  127. END_OF_FILE
  128.   if test 1388 -ne `wc -c <'LEGAL_NOTICE'`; then
  129.     echo shar: \"'LEGAL_NOTICE'\" unpacked with wrong size!
  130.   fi
  131.   # end of 'LEGAL_NOTICE'
  132. fi
  133. if test -f 'var.3++' -a "${1}" != "-c" ; then 
  134.   echo shar: Will not clobber existing file \"'var.3++'\"
  135. else
  136.   echo shar: Extracting \"'var.3++'\" \(15188 characters\)
  137.   sed "s/^X//" >'var.3++' <<'END_OF_FILE'
  138. X.po 6
  139. X.TH VAR 3++ "1/92" "Version 1.0" "Variable Base Type String Class Library"
  140. X
  141. X.SH CLASS
  142. XVAR    \- Variable Base Type String Class Library
  143. X.SH SYNOPSIS
  144. X.B #include     <var.H>
  145. X.PP
  146. X.nf
  147. X.ta.5i 1.0i 4.0i
  148. X\fB
  149. Xclass var {
  150. X
  151. X  public:
  152. X    // Constructors & Destructors
  153. X    var(void);                    // constructor
  154. X    var(const varsize &);            // constructor
  155. X    var(const char *);                // constructor
  156. X    var(const char);                // constructor
  157. X    var(const short);                // constructor
  158. X    var(const unsigned short);            // constructor
  159. X    var(const int);                // constructor
  160. X    var(const unsigned int);            // constructor
  161. X    var(const long);                // constructor
  162. X    var(const unsigned long);            // constructor
  163. X    var(const double);                // constructor
  164. X    var(const var &);                // copy constructor
  165. X    ~var(void);                    // destructor
  166. X
  167. X    // Operators
  168. X    var & operator = (const char *);        // assignment
  169. X    var & operator = (const var &);        // assignment
  170. X    char & operator [] (const int);        // indexing
  171. X    subvar & operator () (int, int) const;    // substring
  172. X    subvar & operator () (const int) const;    // substring
  173. X    friend ostream & operator << (ostream &, const var &); // output
  174. X    friend istream & operator >> (istream &, var &); // input
  175. X    friend class subvar;            // substring
  176. X
  177. X    // More Operators (used for arithmetic type extension)
  178. X    var & operator = (const char);        // assignment
  179. X    var & operator = (const short);        // assignment
  180. X    var & operator = (const unsigned short);    // assignment
  181. X    var & operator = (const int);        // assignment
  182. X    var & operator = (const unsigned int);    // assignment
  183. X    var & operator = (const long);        // assignment
  184. X    var & operator = (const unsigned long);    // assignment
  185. X    var & operator = (const double);        // assignment
  186. X
  187. X    // Casting Operators
  188. X    operator char * (void) const;        // type conversion
  189. X    operator double (void) const;        // type conversion
  190. X
  191. X    // Assignment Operators
  192. X    var & operator ++ (void);            // increment (pre-index only)
  193. X    var & operator -- (void);            // decrement (pre-index only)
  194. X    var operator ! (void) const;        // not
  195. X
  196. X    var operator + (const var &) const;        // addition OR concatenation
  197. X    var operator - (const var &) const;        // subtraction
  198. X    var operator * (const var &) const;        // multiplication
  199. X    var operator / (const var &) const;        // division
  200. X    var operator % (const var &) const;        // remainder
  201. X
  202. X    var & operator += (const var &);        // addition OR concatenation
  203. X    var & operator -= (const var &);        // subtraction
  204. X    var & operator *= (const var &);        // multiplication
  205. X    var & operator /= (const var &);        // division
  206. X    var & operator %= (const var &);        // remainder
  207. X
  208. X    var & operator += (const char &);        // addition OR concatenation
  209. X    var & operator += (const char *);        // addition OR concatenation
  210. X    var & operator -= (const char *);        // subtraction
  211. X    var & operator *= (const char *);        // multiplication
  212. X    var & operator /= (const char *);        // division
  213. X    var & operator %= (const char *);        // remainder
  214. X
  215. X    var & operator += (const double);        // addition OR concatenation
  216. X    var & operator -= (const double);        // subtraction
  217. X    var & operator *= (const double);        // multiplication
  218. X    var & operator /= (const double);        // division
  219. X    var & operator %= (const double);        // remainder
  220. X
  221. X    friend var operator + (const char *, const var &); // addition OR concatenation
  222. X    friend var operator - (const char *, const var &); // subtraction
  223. X    friend var operator * (const char *, const var &); // multiplication
  224. X    friend var operator / (const char *, const var &); // division
  225. X    friend var operator % (const char *, const var &); // remainder
  226. X    friend var operator + (const var &, const char *); // addition OR concatenation
  227. X    friend var operator - (const var &, const char *); // subtraction
  228. X    friend var operator * (const var &, const char *); // multiplication
  229. X    friend var operator / (const var &, const char *); // division
  230. X    friend var operator % (const var &, const char *); // remainder
  231. X
  232. X    friend var operator + (const var &, const double); // addition OR concatenation
  233. X    friend var operator - (const var &, const double); // subtraction
  234. X    friend var operator * (const var &, const double); // multiplication
  235. X    friend var operator / (const var &, const double); // division
  236. X    friend var operator % (const var &, const double); // remainder
  237. X    friend var operator + (const double, const var &); // addition OR concatenation
  238. X    friend var operator - (const double, const var &); // subtraction
  239. X    friend var operator * (const double, const var &); // multiplication
  240. X    friend var operator / (const double, const var &); // division
  241. X    friend var operator % (const double, const var &); // remainder
  242. X
  243. X    // Equality Operators
  244. X    int operator == (const var &) const;    // equality
  245. X    int operator != (const var &) const;    // inequality
  246. X    int operator < (const var &) const;        // less than
  247. X    int operator > (const var &) const;        // greater than
  248. X    int operator <= (const var &) const;    // less than or equal
  249. X    int operator >= (const var &) const;    // greater than or equal
  250. X
  251. X    friend int operator == (const var &, const char *); // equality
  252. X    friend int operator != (const var &, const char *); // inequality
  253. X    friend int operator < (const var &, const char *);  // less than
  254. X    friend int operator > (const var &, const char *);  // greater than
  255. X    friend int operator <= (const var &, const char *); // less than or equal
  256. X    friend int operator >= (const var &, const char *); // greater than or equal
  257. X    friend int operator == (const char *, const var &); // equality
  258. X    friend int operator != (const char *, const var &); // inequality
  259. X    friend int operator < (const char *, const var &);  // less than
  260. X    friend int operator > (const char *, const var &);  // greater than
  261. X    friend int operator <= (const char *, const var &); // less than or equal
  262. X    friend int operator >= (const char *, const var &); // greater than or equal
  263. X
  264. X    friend int operator == (const var &, const double); // equality
  265. X    friend int operator != (const var &, const double); // inequality
  266. X    friend int operator < (const var &, const double);  // less than
  267. X    friend int operator > (const var &, const double);  // greater than
  268. X    friend int operator <= (const var &, const double); // less than or equal
  269. X    friend int operator >= (const var &, const double); // greater than or equal
  270. X    friend int operator == (const double, const var &); // equality
  271. X    friend int operator != (const double, const var &); // inequality
  272. X    friend int operator < (const double, const var &);  // less than
  273. X    friend int operator > (const double, const var &);  // greater than
  274. X    friend int operator <= (const double, const var &); // less than or equal
  275. X    friend int operator >= (const double, const var &); // greater than or equal
  276. X
  277. X    // Custom Interface
  278. X    void null(int);                // "null" out string
  279. X    void changesize(int);            // change allocated memory
  280. X    int length(void) const;            // length of string
  281. X    const char * vartype(void) const;        // name of this var type
  282. X    void change_type(const char *);        // change var type
  283. X    int is_string(void) const;            // test var type
  284. X    int is_double(void) const;            // test var type
  285. X    int is_long(void) const;            // test var type
  286. X    int strchr(const char) const;        // strchr(char) index
  287. X    int strrchr(const char) const;        // strrchr(char) index
  288. X    var & concat(const var &);            // concatenation
  289. X    var & format(const char *);            // set output format
  290. X};
  291. X.fi
  292. X\fP
  293. X
  294. X.SH DESCRIPTION
  295. XClass \fBvar\fP represents a \fBstring\fP object class that also provides all
  296. Xthe traditional functionality of the C base types: char, int, long, float, double, and char*.
  297. X\fBVar\fP, is in many ways a "super-string" class.
  298. XThe var class does a pretty good job of offering a base data "container" object that can either
  299. Xassume its "type" at run time, based on context or remain a "fixed" type, always.
  300. X
  301. X.SS var will do
  302. X.TP 2
  303. X+
  304. Xall the base data types (eg: short, int, long, char *, float, double ...)
  305. X.TP 2
  306. X+
  307. Xstring types
  308. X.TP 2
  309. X+
  310. Xarithmetic
  311. X.TP 2
  312. X+
  313. Xstrings and operations on strings
  314. X.TP 2
  315. X+
  316. Xsub-strings and operations on sub-strings
  317. X.TP 2
  318. X+
  319. Xintelligent "mixing" of operations between mixed types
  320. X.TP 2
  321. X+
  322. Xformatted output using the stream library
  323. X
  324. X.SH PUBLIC CONSTRUCTORS
  325. X.SS var(void);
  326. XThis constructor is used to declare an "untyped" var object.  Type is determined
  327. Xat run-time, based on context of use.
  328. X
  329. X.SS var(const varsize &);
  330. XThis constructor is used to declare an "string" var object, with preallocated memory.
  331. XThe object's type can change at run-time, based on context.
  332. X
  333. X.SS var(const char *);
  334. XThis constructor is used to declare a "string" object initialize from a "char *".
  335. XThe object's type can change at run-time, based on context.
  336. X
  337. X.SS var(const char);
  338. XThis constructor is used to declare an "numeric" var object, initialized from a char.
  339. XThe object's type can change at run-time, based on context.
  340. X
  341. X.SS var(const short);
  342. XThis constructor is used to declare an "numeric" var object, initialized from a short.
  343. XThe object's type is fixed and will not change at run-time.
  344. X
  345. X.SS var(const unsigned short);
  346. XThis constructor is used to declare an "numeric" var object, initialized from an unsigned short.
  347. XThe object's type is fixed and will not change at run-time.
  348. X
  349. X.SS var(const int);
  350. XThis constructor is used to declare an "numeric" var object, initialized from an int.
  351. XThe object's type is fixed and will not change at run-time.
  352. X
  353. X.SS var(const unsigned int);
  354. XThis constructor is used to declare an "numeric" var object, initialized from an unsigned int.
  355. XThe object's type is fixed and will not change at run-time.
  356. X
  357. X.SS var(const long);
  358. XThis constructor is used to declare an "numeric" var object, initialized from a long.
  359. XThe object's type is fixed and will not change at run-time.
  360. X
  361. X.SS var(const unsigned long);
  362. XThis constructor is used to declare an "numeric" var object, initialized from an unsigned long.
  363. XThe object's type is fixed and will not change at run-time.
  364. X
  365. X.SS var(const double);
  366. XThis constructor is used to declare an "numeric" var object, initialized from a double or float.
  367. XThe object's type is fixed and will not change at run-time.
  368. X
  369. X.SS var(const var &);
  370. XThis constructor is used to declare a var object, which is a copy of another var.
  371. XThe object assumes the characteristics of the initializing object.
  372. X
  373. X.SS ~var(void);
  374. XThe destructor returns all memory allocated by the object back to the OS.
  375. X
  376. X
  377. X.SH PUBLIC OPERATORS
  378. X.SS Arithmetic and Concatenation Operators
  379. XMost operators (+, -, /, *, %, +=, etc..) will operate as expected.
  380. XThe "+" and "+=" operators will either do addition or concatenation, as appropriate.
  381. Xif concatenation is required, then the \fB"var.concat(var)"\fP member function should
  382. Xbe used.
  383. X
  384. X.SS Relational Operators
  385. XThese also operate as expected.  If "string" objects are compared, the comparison
  386. Xwill be as performed by \fBstrcmp(3)\fP.
  387. X
  388. X.SS The Indexing Operator []
  389. XYou can index a character from inside a \fBvar\fP by using
  390. Xthe \fB"char & operator [] (const int);"\fP operator.
  391. XA reference to the character is returned, which can be assigned to.
  392. XDo not assign the NULL character using this operator.
  393. XInstead call the member function \fB"null(index)"\fP.
  394. X
  395. X.SS Sub-strings
  396. XTwo operators are provide for substring operation.  The
  397. Xfirst, \fB"subvar & operator () (int start, int length) const;"\fP
  398. Xwill extract a string starting at "start" for "length" characters.
  399. XThe second, \fB"subvar & operator () (const int start) const;"\fP will
  400. Xextract a string starting at "start" to the end of the string.
  401. X
  402. X.SS Type Casting
  403. XOnly two type casts are required by \fBvar\fP. The first converts
  404. Xthe object into a "char *".  The second converts the object into a
  405. Xdouble.  Implicit conversion between "char *" and "double" types
  406. Xwill be performed by your C++ compiler.
  407. X
  408. X.SS Formatted Input/Output
  409. XYou can usr \fBvar\fP with the io stream library.  Object can be
  410. Xboth output and input using the ">>" and "<<" operators.
  411. XFor formatted output, be sure to set the object's "format template"
  412. Xprior to calling the ">>" operator.  (see \fB"var & format(const char *);"\fP)
  413. X
  414. X.SH PUBLIC MEMBER FUNCTIONS
  415. X
  416. X.SS Truncating a string 
  417. XThe \fB"void null(int index);"\fP function will truncate a \fBvar\fP
  418. Xobject, starting from the specified index postion.
  419. X
  420. X.SS Memory Allocation
  421. XThe \fB"void changesize(int newsize);"\fP can be used to increase
  422. Xallocated memory for a var.  Memory can NOT be decreased.  Allocated
  423. Xmemory is returned to the heap when an object goes out of scope.
  424. X
  425. X.SS Determining Var's Length
  426. XThe \fB"int length(void) const;"\fP function returns the "size" of a \fBvar\fP.
  427. X
  428. X.SS Determining Var's Type
  429. XThe \fB"const char * vartype(void) const;"\fP function returns the "type" of a \fBvar\fP.
  430. XPossible types are: "VAR_STRING", "VAR_LONG" and "VAR_DOUBLE".
  431. X
  432. X.SS Explititly Changing a Var's Type
  433. XThe \fB"void change_type(const char *newtype);"\fP function can be used
  434. Xto set an exact type.  Valid values for "newtype" are "string", "short",
  435. X"unsigned short", "int", "unsigned int", "long", "unsigned long",
  436. X"float", and "double".
  437. X
  438. X.SS Testing a Var's Type
  439. XThree functions are provided that allow testing a \fBvar\fP type.
  440. XThey are as follows: \fB"int is_string(void) const;"\fP,
  441. X\fB"int is_double(void) const;"\fP, and \fB"int is_long(void) const;"\fP
  442. X
  443. X.SS Searching for a Character
  444. XTwo functions are provided that search a \fBvar\fP for a specified
  445. Xcharacter.  Both return an offset.  The first \fB"int strchr(const char) const;"\fP
  446. Xsearches forward.  The second, \fB"int strrchr(const char) const;"\fP
  447. Xsearches backward.
  448. X
  449. X.SS Concatenation
  450. XConcatenation can be forced, regardless of type with the \fB"var & concat(const var &);"\fP
  451. Xfunction.
  452. X
  453. X.SS Setting the Output Format
  454. XThe \fB"var & format(const char *fmt);"\fP function will allow you to specify an
  455. Xoutput format.  This format will remain in effect until changed.  Printf()
  456. Xstyle output formats can be introduced anywhere in the format statment.
  457. XMultiple formateed output directives can appear in the same "fmt".  Each
  458. Xdirective will receive a copy of the object.  Automatic type conversion will
  459. Xoccur.
  460. X
  461. X
  462. X.SH AUTHOR
  463. XLee Hounshell - 1/92
  464. X
  465. X.SH EXAMPLE
  466. X.nf
  467. X#include    <stdlib.h>
  468. X#include    <stream.h>
  469. X#include    <var.H>
  470. X
  471. Xmain ()
  472. X{
  473. X    var value;                // declare an "untyped" var
  474. X    value = "hello world";        // initialize it
  475. X    cout << value << endl;        // output "hello world"
  476. X    value = value(3, value.length() - 6); // substring example
  477. X    cout << value << endl;        // output "lo wo"
  478. X    value = 35;                // assignment of int
  479. X    value += 42.375;            // add 42.375 to present value
  480. X    cout << value << endl;        // output "77.375"
  481. X    cout << value.format("formatted output example %05d of value") << endl;
  482. X    cout << value.format("multiple outputs #1=%d, #2=%9.2f of value") << endl;
  483. X    value.null(2);            // truncate string
  484. X    value += " sunset strip";        // concatenate a string
  485. X    cout << value.format("%s") << endl;    // output "77 sunset strip"
  486. X    cout << value[3] << value[4] << value[5] << endl; // output "sun"
  487. X}
  488. X.fi
  489. X
  490. X.SH SUPERCLASSES
  491. Xnone.
  492. X
  493. X.SH SUBCLASSES
  494. Xnone
  495. X
  496. X.SH BUGS
  497. XAssignment of an array of vars to another array of vars
  498. Xmust currently be done one elemnt at a time.
  499. X
  500. END_OF_FILE
  501.   if test 15188 -ne `wc -c <'var.3++'`; then
  502.     echo shar: \"'var.3++'\" unpacked with wrong size!
  503.   fi
  504.   # end of 'var.3++'
  505. fi
  506. if test -f 'var.C' -a "${1}" != "-c" ; then 
  507.   echo shar: Will not clobber existing file \"'var.C'\"
  508. else
  509.   echo shar: Extracting \"'var.C'\" \(30983 characters\)
  510.   sed "s/^X//" >'var.C' <<'END_OF_FILE'
  511. X//
  512. X// NAME:    var.C
  513. X//
  514. X// PURPOSE:    C++ Generic "Universal Variable" library class
  515. X// AUTHOR:    Lee Hounshell
  516. X//
  517. X
  518. X#include    <stddef.h>
  519. X#include    <stream.h>
  520. X#include    <stdlib.h>
  521. X#include    <ctype.h>
  522. X#include    <string.h>
  523. X#include    "var.H"
  524. X#include    "Misc.H"
  525. X
  526. Xconst int    VAR_PAD_SIZE        = 128;
  527. Xconst int    VAR_DEF_SIZE        = 16;
  528. X
  529. Xconst short    VAR_STRING        = 0;
  530. Xconst short    VAR_LONG        = 1;
  531. Xconst short    VAR_DOUBLE        = 2;
  532. X
  533. Xchar *    DEFAULT_STRING_FORMAT        = "'%s'";
  534. Xchar *    DEFAULT_INT_FORMAT        = "%d";
  535. Xchar *    DEFAULT_UINT_FORMAT        = "%u";
  536. Xchar *    DEFAULT_LONG_FORMAT        = "%ld";
  537. Xchar *    DEFAULT_ULONG_FORMAT        = "%lu";
  538. Xchar *    DEFAULT_DOUBLE_FORMAT        = "%9.2f";
  539. X
  540. X// -----------------------------------------------------------------------------
  541. X
  542. Xconst var var::ctype    = "var";
  543. Xint var::save_me            = 1;
  544. X
  545. X
  546. Xconst var & var::type(void) const
  547. X{
  548. X    return var::ctype;
  549. X}
  550. X
  551. X
  552. Xvarsize::varsize(int sz)
  553. X{
  554. X    size = sz;
  555. X}
  556. X
  557. X
  558. Xvar::var(void)
  559. X{
  560. X    fixed = 0;
  561. X    is_numeric = VAR_STRING;
  562. X    data_str_len = VAR_DEF_SIZE;
  563. X    data_str_end = 0;
  564. X    data_str = new char[data_str_len];
  565. X    data_str[0] = 0;
  566. X    format_str = DEFAULT_STRING_FORMAT;
  567. X}
  568. X
  569. X
  570. Xvar::var(const char *str)
  571. X{
  572. X    fixed = 1;
  573. X    is_numeric = VAR_STRING;
  574. X    data_str_end = strlen(str);
  575. X    data_str_len = data_str_end + VAR_DEF_SIZE;
  576. X    data_str = new char[data_str_len];
  577. X    strcpy(data_str, str);
  578. X    format_str = DEFAULT_STRING_FORMAT;
  579. X}
  580. X
  581. X
  582. Xvar::var(const varsize &vsz)
  583. X{
  584. X    fixed = 0;
  585. X    is_numeric = VAR_STRING;
  586. X    data_str_len = vsz.size + VAR_DEF_SIZE;
  587. X    data_str_end = 0;
  588. X    data_str = new char[data_str_len];
  589. X    data_str[0] = 0;
  590. X    format_str = DEFAULT_STRING_FORMAT;
  591. X}
  592. X
  593. X
  594. Xvar::var(const char ch)
  595. X{
  596. X    fixed = 0;
  597. X    is_numeric = VAR_STRING;
  598. X    data_str_len = VAR_DEF_SIZE;
  599. X    data_str_end = 1;
  600. X    data_str = new char[data_str_len];
  601. X    data_str[0] = ch;
  602. X    data_str[1] = 0;
  603. X    format_str = DEFAULT_STRING_FORMAT;
  604. X}
  605. X
  606. X
  607. Xvar::var(const short int_num)
  608. X{
  609. X    fixed = 1;
  610. X    is_numeric = VAR_LONG;
  611. X    data_str_len = VAR_DEF_SIZE;
  612. X    data_str = new char[data_str_len];
  613. X    strcpy(data_str, itoa(int_num));
  614. X    data_str_end = strlen(data_str);
  615. X    format_str = DEFAULT_INT_FORMAT;
  616. X}
  617. X
  618. X
  619. Xvar::var(const unsigned short int_num)
  620. X{
  621. X    fixed = 1;
  622. X    is_numeric = VAR_LONG;
  623. X    data_str_len = VAR_DEF_SIZE;
  624. X    data_str = new char[data_str_len];
  625. X    strcpy(data_str, itoa(int_num));
  626. X    data_str_end = strlen(data_str);
  627. X    format_str = DEFAULT_UINT_FORMAT;
  628. X}
  629. X
  630. X
  631. Xvar::var(const int int_num)
  632. X{
  633. X    fixed = 1;
  634. X    is_numeric = VAR_LONG;
  635. X    data_str_len = VAR_DEF_SIZE;
  636. X    data_str = new char[data_str_len];
  637. X    strcpy(data_str, itoa(int_num));
  638. X    data_str_end = strlen(data_str);
  639. X    format_str = DEFAULT_INT_FORMAT;
  640. X}
  641. X
  642. X
  643. Xvar::var(const unsigned int int_num)
  644. X{
  645. X    fixed = 1;
  646. X    is_numeric = VAR_LONG;
  647. X    data_str_len = VAR_DEF_SIZE;
  648. X    data_str = new char[data_str_len];
  649. X    strcpy(data_str, itoa(int_num));
  650. X    data_str_end = strlen(data_str);
  651. X    format_str = DEFAULT_UINT_FORMAT;
  652. X}
  653. X
  654. X
  655. Xvar::var(const long long_num)
  656. X{
  657. X    fixed = 1;
  658. X    is_numeric = VAR_LONG;
  659. X    data_str_len = VAR_DEF_SIZE;
  660. X    data_str = new char[data_str_len];
  661. X    strcpy(data_str, ltoa(long_num));
  662. X    data_str_end = strlen(data_str);
  663. X    format_str = DEFAULT_LONG_FORMAT;
  664. X}
  665. X
  666. X
  667. Xvar::var(const unsigned long long_num)
  668. X{
  669. X    fixed = 1;
  670. X    is_numeric = VAR_LONG;
  671. X    data_str_len = VAR_DEF_SIZE;
  672. X    data_str = new char[data_str_len];
  673. X    strcpy(data_str, ltoa(long_num));
  674. X    data_str_end = strlen(data_str);
  675. X    format_str = DEFAULT_ULONG_FORMAT;
  676. X}
  677. X
  678. X
  679. Xvar::var(const double double_num)
  680. X{
  681. X    fixed = 1;
  682. X    is_numeric = VAR_DOUBLE;
  683. X    data_str_len = VAR_DEF_SIZE;
  684. X    data_str = new char[data_str_len];
  685. X    strcpy(data_str, dtoa(double_num));
  686. X    data_str_end = strlen(data_str);
  687. X    format_str = DEFAULT_DOUBLE_FORMAT;
  688. X}
  689. X
  690. X
  691. Xvar::var(const var &v)
  692. X{
  693. X    fixed = v.fixed;
  694. X    is_numeric = v.is_numeric;
  695. X    if (v.data_str && v.data_str_end) {
  696. X    data_str_len = v.data_str_end + VAR_DEF_SIZE;
  697. X    data_str_end = v.data_str_end;
  698. X    data_str = new char[data_str_len];
  699. X    strcpy(data_str, v.data_str);
  700. X    }
  701. X    else {
  702. X    data_str_len = VAR_DEF_SIZE;
  703. X    data_str_end = 0;
  704. X    data_str = new char[data_str_len];
  705. X    data_str[0] = 0;
  706. X    }
  707. X    format_str = DEFAULT_STRING_FORMAT;
  708. X}
  709. X
  710. X
  711. Xvar::~var(void)
  712. X{
  713. X    if (data_str) {
  714. X    delete data_str;
  715. X    }
  716. X    if (format_str
  717. X    && format_str != DEFAULT_STRING_FORMAT
  718. X    && format_str != DEFAULT_INT_FORMAT
  719. X    && format_str != DEFAULT_UINT_FORMAT
  720. X    && format_str != DEFAULT_LONG_FORMAT
  721. X    && format_str != DEFAULT_ULONG_FORMAT
  722. X    && format_str != DEFAULT_DOUBLE_FORMAT) {
  723. X        delete format_str;
  724. X    }
  725. X}
  726. X
  727. X// -----------------------------------------------------------------------------
  728. X
  729. Xvar & var::operator = (const char *str)
  730. X{
  731. X    if (fixed && is_numeric) {
  732. X    if (is_numeric == VAR_DOUBLE) {
  733. X        double d = atod((char *) str);
  734. X        *this = d;
  735. X    }
  736. X    else {
  737. X        long l = atol(str);
  738. X        *this = l;
  739. X    }
  740. X    }
  741. X    else {
  742. X    int len = strlen(str) + 1;
  743. X    if (data_str_len < len) {
  744. X        delete data_str;
  745. X        data_str_len = len;
  746. X        data_str = new char[data_str_len];
  747. X    }
  748. X    data_str_end = len - 1;
  749. X    strcpy(data_str, str);
  750. X    if (!fixed) {
  751. X        int str_is_numeric = numcheck(data_str);
  752. X        is_numeric = str_is_numeric;
  753. X    }
  754. X    }
  755. X    return *this;
  756. X}
  757. X
  758. X
  759. Xvar & var::operator = (const var &l)
  760. X{
  761. X    if (this != &l) {
  762. X    if (data_str_len <= l.data_str_end) {
  763. X        delete data_str;
  764. X        data_str_len = l.data_str_end + VAR_DEF_SIZE;
  765. X        data_str = new char[data_str_len];
  766. X    }
  767. X    data_str_end = l.data_str_end;
  768. X    strncpy(data_str, l.data_str, l.data_str_end);
  769. X    data_str[data_str_end] = 0;
  770. X    if (!fixed) {
  771. X        is_numeric = numcheck(data_str);
  772. X    }
  773. X    //
  774. X    // Note: the output "format" of a var variable is preserved
  775. X    //
  776. X    }
  777. X    return *this;
  778. X}
  779. X
  780. X
  781. Xchar & var::operator [] (const int index)
  782. X{
  783. X    static char error_ch;
  784. X    if (index < 0) {
  785. X    cerr << "ERROR: " << " - var[" << index << "] negative index used." << endl;
  786. X    error_ch = 0;
  787. X    return error_ch;
  788. X    }
  789. X    if (data_str_len <= index) {
  790. X    // this is technically a program error, but I'll be nice and extend the string's length
  791. X    data_str_len = index + VAR_PAD_SIZE;
  792. X    data_str_end = index + 1;
  793. X    char *buf = new char[data_str_len];
  794. X    sprintf(buf, "%-*.*s", data_str_end, data_str_end, data_str);
  795. X    delete data_str;
  796. X    data_str = buf;
  797. X    data_str[index] = 0;
  798. X    cerr << "WARNING: " << " - var index '" << index << "' beyond current string boundary." << endl;
  799. X    }
  800. X    while (data_str_end < index) {
  801. X    data_str[data_str_end++] = ' ';        // pad to index with spaces if necessary
  802. X    }
  803. X    if (data_str_end == index) {
  804. X    data_str[data_str_end] = 0;        // the end of a string is ALWAYS 0
  805. X    if ((data_str_end + 1) < data_str_len) {
  806. X        data_str[++data_str_end] = 0;    // the new end of string is also 0
  807. X    }
  808. X    }
  809. X    return data_str[index];
  810. X}
  811. X
  812. X
  813. X// for substrings
  814. Xsubvar & var::operator () (const int offset) const
  815. X{
  816. X    return operator () (offset, -1);
  817. X}
  818. X
  819. X
  820. X// for substrings
  821. Xsubvar & var::operator () (int offset, int length) const
  822. X{
  823. X    static subvar _esi_subvar;
  824. X    if (length < 0) {
  825. X    length = data_str_end - offset;
  826. X    }
  827. X    char *substr = new char[length + 1];
  828. X    strncpy(substr, data_str + offset, (int) length);
  829. X    substr[length] = 0;
  830. X    _esi_subvar.var::operator = (substr);
  831. X    _esi_subvar.varptr = (var *) this;
  832. X    _esi_subvar.offset = offset;
  833. X    _esi_subvar.length = length;
  834. X    delete substr;
  835. X    return _esi_subvar;
  836. X}
  837. X
  838. X
  839. X// for syntax: var(offset, length) = var
  840. Xvar & subvar::operator = (const var &substr)
  841. X{
  842. X    char *srcstr = varptr->data_str;
  843. X    char *repstr = substr.data_str;
  844. X    int replen = length;
  845. X    if (substr.data_str_end < length) {
  846. X    replen = substr.data_str_end;
  847. X    }
  848. X    int len = varptr->data_str_len;
  849. X    char *newstr = new char[len];
  850. X    strncpy(newstr, srcstr, offset);        // data from string being replaced up to "offset"
  851. X    if (replen) {
  852. X    strncpy(newstr + offset, repstr, replen);    // replacement string data
  853. X    }
  854. X    int newoffset = offset + replen;
  855. X    if (newoffset < varptr->data_str_end) {
  856. X    strcpy(newstr + newoffset, srcstr + offset + length);
  857. X    }
  858. X    else {
  859. X    newstr[newoffset] = 0;
  860. X    }
  861. X    if (varptr->data_str) {
  862. X    delete varptr->data_str;
  863. X    }
  864. X    varptr->data_str = newstr;
  865. X    varptr->data_str_len = len;
  866. X    varptr->data_str_end = strlen(newstr);
  867. X    if (!varptr->fixed) {
  868. X    varptr->is_numeric = numcheck(newstr);
  869. X    }
  870. X    return *varptr;
  871. X}
  872. X
  873. X// -----------------------------------------------------------------------------
  874. X
  875. Xvar & var::operator = (const char ch)
  876. X{
  877. X    char buf[2];
  878. X    buf[0] = ch;
  879. X    buf[1] = 0;
  880. X    *this = buf;
  881. X    return *this;
  882. X}
  883. X
  884. X
  885. Xvar & var::operator = (const short int_num)
  886. X{
  887. X    char *str = itoa(int_num);
  888. X    int len = strlen(str);
  889. X    if (data_str_len < len) {
  890. X    delete data_str;
  891. X    data_str_len = len + 1;
  892. X    data_str = new char[data_str_len];
  893. X    }
  894. X    data_str_end = len;
  895. X    strcpy(data_str, str);
  896. X    if (!fixed) {
  897. X    is_numeric = VAR_LONG;
  898. X    }
  899. X    return *this;
  900. X}
  901. X
  902. X
  903. Xvar & var::operator = (const unsigned short int_num)
  904. X{
  905. X    char *str = itoa(int_num);
  906. X    int len = strlen(str);
  907. X    if (data_str_len < len) {
  908. X    delete data_str;
  909. X    data_str_len = len + 1;
  910. X    data_str = new char[data_str_len];
  911. X    }
  912. X    data_str_end = len;
  913. X    strcpy(data_str, str);
  914. X    is_numeric = VAR_LONG;
  915. X    return *this;
  916. X}
  917. X
  918. X
  919. Xvar & var::operator = (const int int_num)
  920. X{
  921. X    char *str = itoa(int_num);
  922. X    int len = strlen(str);
  923. X    if (data_str_len < len) {
  924. X    delete data_str;
  925. X    data_str_len = len + 1;
  926. X    data_str = new char[data_str_len];
  927. X    }
  928. X    data_str_end = len;
  929. X    strcpy(data_str, str);
  930. X    if (!fixed) {
  931. X    is_numeric = VAR_LONG;
  932. X    }
  933. X    return *this;
  934. X}
  935. X
  936. X
  937. Xvar & var::operator = (const unsigned int int_num)
  938. X{
  939. X    char *str = itoa(int_num);
  940. X    int len = strlen(str);
  941. X    if (data_str_len < len) {
  942. X    delete data_str;
  943. X    data_str_len = len + 1;
  944. X    data_str = new char[data_str_len];
  945. X    }
  946. X    data_str_end = len;
  947. X    strcpy(data_str, str);
  948. X    if (!fixed) {
  949. X    is_numeric = VAR_LONG;
  950. X    }
  951. X    return *this;
  952. X}
  953. X
  954. X
  955. Xvar & var::operator = (const long long_num)
  956. X{
  957. X    char *str = ltoa(long_num);
  958. X    int len = strlen(str);
  959. X    if (data_str_len < len) {
  960. X    delete data_str;
  961. X    data_str_len = len + 1;
  962. X    data_str = new char[data_str_len];
  963. X    }
  964. X    data_str_end = len;
  965. X    strcpy(data_str, str);
  966. X    if (!fixed) {
  967. X    is_numeric = VAR_LONG;
  968. X    }
  969. X    return *this;
  970. X}
  971. X
  972. X
  973. Xvar & var::operator = (const unsigned long long_num)
  974. X{
  975. X    char *str = ltoa(long_num);
  976. X    int len = strlen(str);
  977. X    if (data_str_len < len) {
  978. X    delete data_str;
  979. X    data_str_len = len + 1;
  980. X    data_str = new char[data_str_len];
  981. X    }
  982. X    data_str_end = len;
  983. X    strcpy(data_str, str);
  984. X    if (!fixed) {
  985. X    is_numeric = VAR_LONG;
  986. X    }
  987. X    return *this;
  988. X}
  989. X
  990. X
  991. Xvar & var::operator = (const double dbl_num)
  992. X{
  993. X    char *str = dtoa(dbl_num);
  994. X    int len = strlen(str);
  995. X    if (data_str_len < len) {
  996. X    delete data_str;
  997. X    data_str_len = len + 1;
  998. X    data_str = new char[data_str_len];
  999. X    }
  1000. X    data_str_end = len;
  1001. X    strcpy(data_str, str);
  1002. X    if (!fixed) {
  1003. X    is_numeric = VAR_DOUBLE;
  1004. X    }
  1005. X    return *this;
  1006. X}
  1007. X
  1008. X// -----------------------------------------------------------------------------
  1009. X
  1010. Xvar::operator char * (void) const
  1011. X{
  1012. X    return data_str;
  1013. X}
  1014. X
  1015. X
  1016. Xvar::operator double (void) const
  1017. X{
  1018. X    return atod(data_str);
  1019. X}
  1020. X
  1021. X// -----------------------------------------------------------------------------
  1022. X
  1023. Xvar & var::operator ++ (void)        // increment (pre-index only)
  1024. X{
  1025. X    *this += 1;
  1026. X    return *this;
  1027. X}
  1028. X
  1029. X
  1030. Xvar & var::operator -- (void)        // decrement (pre-index only)
  1031. X{
  1032. X    *this -= 1;
  1033. X    return *this;
  1034. X}
  1035. X
  1036. X
  1037. Xvar var::operator ! (void) const    // not
  1038. X{
  1039. X    var not(1);
  1040. X    if ((int) *this) {
  1041. X    not = 0;
  1042. X    }
  1043. X    return not;
  1044. X}
  1045. X
  1046. X// -----------------------------------------------------------------------------
  1047. X
  1048. Xvar var::operator + (const var & v) const    // addition OR concatenation
  1049. X{
  1050. X    var add;
  1051. X    if (is_numeric && v.is_numeric) {
  1052. X    // do math in the highest precision specified
  1053. X    int n_type = (is_numeric > v.is_numeric) ? is_numeric : v.is_numeric;
  1054. X    switch (n_type) {
  1055. X        case VAR_LONG:
  1056. X        add = (long) *this + (long) v;
  1057. X        break;
  1058. X        default:
  1059. X        // should be VAR_DOUBLE
  1060. X        add = (double) *this + (double) v;
  1061. X        break;
  1062. X    }
  1063. X    }
  1064. X    else {
  1065. X    // concatenate strings
  1066. X    delete add.data_str;
  1067. X    add.data_str_len = data_str_end + v.data_str_end + VAR_PAD_SIZE;
  1068. X    add.data_str_end = data_str_end + v.data_str_end;
  1069. X    add.data_str = new char[add.data_str_len];
  1070. X    strcpy(add.data_str, data_str);
  1071. X    strcpy((add.data_str) + data_str_end, v.data_str);
  1072. X    add.is_numeric = VAR_STRING;
  1073. X    }
  1074. X    return add;
  1075. X}
  1076. X
  1077. X
  1078. Xvar var::operator - (const var & v) const    // subtraction
  1079. X{
  1080. X    var sub;
  1081. X    // do math in the highest precision specified
  1082. X    int n_type = (is_numeric > v.is_numeric) ? is_numeric : v.is_numeric;
  1083. X    switch (n_type) {
  1084. X    case VAR_LONG:
  1085. X        sub = (long) *this - (long) v;
  1086. X        sub.is_numeric = VAR_LONG;
  1087. X        break;
  1088. X    default:
  1089. X        // should be VAR_DOUBLE
  1090. X        sub = (double) *this - (double) v;
  1091. X        break;
  1092. X    }
  1093. X    return sub;
  1094. X}
  1095. X
  1096. X
  1097. Xvar var::operator * (const var & v) const    // multiplication
  1098. X{
  1099. X    var times;
  1100. X    // do math in the highest precision specified
  1101. X    int n_type = (is_numeric > v.is_numeric) ? is_numeric : v.is_numeric;
  1102. X    switch (n_type) {
  1103. X    case VAR_LONG:
  1104. X        times = (long) *this * (long) v;
  1105. X        break;
  1106. X    default:
  1107. X        // should be VAR_DOUBLE
  1108. X        times = (double) *this * (double) v;
  1109. X        break;
  1110. X    }
  1111. X    return times;
  1112. X}
  1113. X
  1114. X
  1115. Xvar var::operator / (const var & v) const    // division
  1116. X{
  1117. X    var div;
  1118. X    // do math in the highest precision specified
  1119. X    int n_type = (is_numeric > v.is_numeric) ? is_numeric : v.is_numeric;
  1120. X    switch (n_type) {
  1121. X    case VAR_LONG:
  1122. X        div = (long) *this / (long) v;
  1123. X        break;
  1124. X    default:
  1125. X        // should be VAR_DOUBLE
  1126. X        div = (double) *this / (double) v;
  1127. X        break;
  1128. X    }
  1129. X    return div;
  1130. X}
  1131. X
  1132. X
  1133. Xvar var::operator % (const var & v) const    // remainder
  1134. X{
  1135. X    var mod;
  1136. X    // do math in the highest precision specified
  1137. X    int n_type = (is_numeric > v.is_numeric) ? is_numeric : v.is_numeric;
  1138. X    switch (n_type) {
  1139. X    case VAR_LONG:
  1140. X        mod = (long) *this % (long) v;
  1141. X        break;
  1142. X    default:
  1143. X        // should be VAR_DOUBLE
  1144. X        // really, I shouldn't allow this..
  1145. X        mod = (double) ((long) *this % (long) v);
  1146. X        break;
  1147. X    }
  1148. X    return mod;
  1149. X}
  1150. X
  1151. X// -----------------------------------------------------------------------------
  1152. X
  1153. Xvar & var::operator += (const var & v)
  1154. X{
  1155. X    if ((is_numeric == VAR_STRING) || (v.is_numeric == VAR_STRING)) {
  1156. X    concat(v);
  1157. X    }
  1158. X    else {
  1159. X    *this = (*this) + v;
  1160. X    }
  1161. X    return *this;
  1162. X}
  1163. X
  1164. X
  1165. Xvar & var::operator -= (const var & v)
  1166. X{
  1167. X    *this = (*this) - v;
  1168. X    return *this;
  1169. X}
  1170. X
  1171. X
  1172. Xvar & var::operator *= (const var & v)
  1173. X{
  1174. X    *this = (*this) * v;
  1175. X    return *this;
  1176. X}
  1177. X
  1178. X
  1179. Xvar & var::operator /= (const var & v)
  1180. X{
  1181. X    *this = (*this) / v;
  1182. X    return *this;
  1183. X}
  1184. X
  1185. X
  1186. Xvar & var::operator %= (const var & v)
  1187. X{
  1188. X    *this = (*this) % v;
  1189. X    return *this;
  1190. X}
  1191. X
  1192. X// -----------------------------------------------------------------------------
  1193. X
  1194. Xvar & var::operator += (const char & ch)
  1195. X{
  1196. X    var foo = ch;
  1197. X    *this += foo;
  1198. X    return *this;
  1199. X}
  1200. X
  1201. Xvar & var::operator += (const char * v)
  1202. X{
  1203. X    var foo = v;
  1204. X    *this += foo;
  1205. X    return *this;
  1206. X}
  1207. X
  1208. X
  1209. Xvar & var::operator -= (const char * v)
  1210. X{
  1211. X    var foo = v;
  1212. X    *this -= foo;
  1213. X    return *this;
  1214. X}
  1215. X
  1216. X
  1217. Xvar & var::operator *= (const char * v)
  1218. X{
  1219. X    var foo = v;
  1220. X    *this *= foo;
  1221. X    return *this;
  1222. X}
  1223. X
  1224. X
  1225. Xvar & var::operator /= (const char * v)
  1226. X{
  1227. X    var foo = v;
  1228. X    *this /= foo;
  1229. X    return *this;
  1230. X}
  1231. X
  1232. X
  1233. Xvar & var::operator %= (const char * v)
  1234. X{
  1235. X    var foo = v;
  1236. X    *this %= foo;
  1237. X    return *this;
  1238. X}
  1239. X
  1240. X// -----------------------------------------------------------------------------
  1241. X
  1242. Xvar & var::operator += (const double v)
  1243. X{
  1244. X    var foo = v;
  1245. X    *this += foo;
  1246. X    return *this;
  1247. X}
  1248. X
  1249. X
  1250. Xvar & var::operator -= (const double v)
  1251. X{
  1252. X    var foo = v;
  1253. X    *this -= foo;
  1254. X    return *this;
  1255. X}
  1256. X
  1257. X
  1258. Xvar & var::operator *= (const double v)
  1259. X{
  1260. X    var foo = v;
  1261. X    *this *= foo;
  1262. X    return *this;
  1263. X}
  1264. X
  1265. X
  1266. Xvar & var::operator /= (const double v)
  1267. X{
  1268. X    var foo = v;
  1269. X    *this /= foo;
  1270. X    return *this;
  1271. X}
  1272. X
  1273. X
  1274. Xvar & var::operator %= (const double v)
  1275. X{
  1276. X    var foo = v;
  1277. X    *this %= foo;
  1278. X    return *this;
  1279. X}
  1280. X
  1281. X// -----------------------------------------------------------------------------
  1282. X
  1283. Xvar operator + (const char * s, const var & v)
  1284. X{
  1285. X    var foo = s;
  1286. X    return foo + v;
  1287. X}
  1288. X
  1289. X
  1290. Xvar operator - (const char * s, const var & v)
  1291. X{
  1292. X    var foo = s;
  1293. X    return foo - v;
  1294. X}
  1295. X
  1296. X
  1297. Xvar operator * (const char * s, const var & v)
  1298. X{
  1299. X    var foo = s;
  1300. X    return foo * v;
  1301. X}
  1302. X
  1303. X
  1304. Xvar operator / (const char * s, const var & v)
  1305. X{
  1306. X    var foo = s;
  1307. X    return foo / v;
  1308. X}
  1309. X
  1310. X
  1311. Xvar operator % (const char * s, const var & v)
  1312. X{
  1313. X    var foo = s;
  1314. X    return foo % v;
  1315. X}
  1316. X
  1317. X
  1318. Xvar operator + (const var & v, const char * s)
  1319. X{
  1320. X    var foo = s;
  1321. X    return v + foo;
  1322. X}
  1323. X
  1324. X
  1325. Xvar operator - (const var & v, const char * s)
  1326. X{
  1327. X    var foo = s;
  1328. X    return v - foo;
  1329. X}
  1330. X
  1331. X
  1332. Xvar operator * (const var & v, const char * s)
  1333. X{
  1334. X    var foo = s;
  1335. X    return v * foo;
  1336. X}
  1337. X
  1338. X
  1339. Xvar operator / (const var & v, const char * s)
  1340. X{
  1341. X    var foo = s;
  1342. X    return v / foo;
  1343. X}
  1344. X
  1345. X
  1346. Xvar operator % (const var & v, const char * s)
  1347. X{
  1348. X    var foo = s;
  1349. X    return v % foo;
  1350. X}
  1351. X
  1352. X// -----------------------------------------------------------------------------
  1353. X
  1354. Xvar operator + (const var & v, const double d)
  1355. X{
  1356. X    var foo = d;
  1357. X    return v + foo;
  1358. X}
  1359. X
  1360. X
  1361. Xvar operator - (const var & v, const double d)
  1362. X{
  1363. X    var foo = d;
  1364. X    return v - foo;
  1365. X}
  1366. X
  1367. X
  1368. Xvar operator * (const var & v, const double d)
  1369. X{
  1370. X    var foo = d;
  1371. X    return v * foo;
  1372. X}
  1373. X
  1374. X
  1375. Xvar operator / (const var & v, const double d)
  1376. X{
  1377. X    var foo = d;
  1378. X    return v / foo;
  1379. X}
  1380. X
  1381. X
  1382. Xvar operator % (const var & v, const double d)
  1383. X{
  1384. X    var foo = d;
  1385. X    return v % foo;
  1386. X}
  1387. X
  1388. X
  1389. Xvar operator + (const double d, const var & v)
  1390. X{
  1391. X    var foo = d;
  1392. X    return foo + v;
  1393. X}
  1394. X
  1395. X
  1396. Xvar operator - (const double d, const var & v)
  1397. X{
  1398. X    var foo = d;
  1399. X    return foo - v;
  1400. X}
  1401. X
  1402. X
  1403. Xvar operator * (const double d, const var & v)
  1404. X{
  1405. X    var foo = d;
  1406. X    return foo * v;
  1407. X}
  1408. X
  1409. X
  1410. Xvar operator / (const double d, const var & v)
  1411. X{
  1412. X    var foo = d;
  1413. X    return foo / v;
  1414. X}
  1415. X
  1416. X
  1417. Xvar operator % (const double d, const var & v)
  1418. X{
  1419. X    var foo = d;
  1420. X    return foo % v;
  1421. X}
  1422. X
  1423. X// -----------------------------------------------------------------------------
  1424. X
  1425. Xint var::operator == (const var & t) const        // equality
  1426. X{
  1427. X    if (is_numeric && t.is_numeric) {
  1428. X    if (is_numeric == VAR_LONG && t.is_numeric == VAR_LONG) {
  1429. X        return (long) (*this) == (long) t;
  1430. X    }
  1431. X    return (double) (*this) == (double) t;
  1432. X    }
  1433. X    else {
  1434. X    if (data_str_end && t.data_str_end) {
  1435. X        return !strcmp(data_str, t.data_str);
  1436. X    }
  1437. X    else {
  1438. X        return data_str_end == t.data_str_end;
  1439. X    }
  1440. X    }
  1441. X}
  1442. X
  1443. X
  1444. Xint var::operator != (const var & t) const        // inequality
  1445. X{
  1446. X    if (is_numeric && t.is_numeric) {
  1447. X    if (is_numeric == VAR_LONG && t.is_numeric == VAR_LONG) {
  1448. X        return (long) (*this) != (long) t;
  1449. X    }
  1450. X    return (double) (*this) != (double) t;
  1451. X    }
  1452. X    else {
  1453. X    if (data_str_end && t.data_str_end) {
  1454. X        return strcmp(data_str, t.data_str);
  1455. X    }
  1456. X    else {
  1457. X        return data_str_end != t.data_str_end;
  1458. X    }
  1459. X    }
  1460. X}
  1461. X
  1462. X
  1463. Xint var::operator < (const var & t) const        // less than
  1464. X{
  1465. X    if (is_numeric && t.is_numeric) {
  1466. X    if (is_numeric == VAR_LONG && t.is_numeric == VAR_LONG) {
  1467. X        return (long) (*this) < (long) t;
  1468. X    }
  1469. X    return (double) (*this) < (double) t;
  1470. X    }
  1471. X    else {
  1472. X    if (data_str_end && t.data_str_end) {
  1473. X        return (strcmp(data_str, t.data_str) < 0);
  1474. X    }
  1475. X    else {
  1476. X        return data_str_end < t.data_str_end;
  1477. X    }
  1478. X    }
  1479. X}
  1480. X
  1481. X
  1482. Xint var::operator > (const var & t) const        // greater than
  1483. X{
  1484. X    if (is_numeric && t.is_numeric) {
  1485. X    if (is_numeric == VAR_LONG && t.is_numeric == VAR_LONG) {
  1486. X        return (long) (*this) > (long) t;
  1487. X    }
  1488. X    return (double) (*this) > (double) t;
  1489. X    }
  1490. X    else {
  1491. X    if (data_str_end && t.data_str_end) {
  1492. X        return (strcmp(data_str, t.data_str) > 0);
  1493. X    }
  1494. X    else {
  1495. X        return data_str_end > t.data_str_end;
  1496. X    }
  1497. X    }
  1498. X}
  1499. X
  1500. X
  1501. Xint var::operator <= (const var & t) const        // less than or equal
  1502. X{
  1503. X    if (is_numeric && t.is_numeric) {
  1504. X    if (is_numeric == VAR_LONG && t.is_numeric == VAR_LONG) {
  1505. X        return (long) (*this) <= (long) t;
  1506. X    }
  1507. X    return (double) (*this) <= (double) t;
  1508. X    }
  1509. X    else {
  1510. X    if (data_str_end && t.data_str_end) {
  1511. X        return (strcmp(data_str, t.data_str) <= 0);
  1512. X    }
  1513. X    else {
  1514. X        return data_str_end <= t.data_str_end;
  1515. X    }
  1516. X    }
  1517. X}
  1518. X
  1519. X
  1520. Xint var::operator >= (const var & t) const        // greater than or equal
  1521. X{
  1522. X    if (is_numeric && t.is_numeric) {
  1523. X    if (is_numeric == VAR_LONG && t.is_numeric == VAR_LONG) {
  1524. X        return (long) (*this) >= (long) t;
  1525. X    }
  1526. X    return (double) (*this) >= (double) t;
  1527. X    }
  1528. X    else {
  1529. X    if (data_str_end && t.data_str_end) {
  1530. X        return (strcmp(data_str, t.data_str) >= 0);
  1531. X    }
  1532. X    else {
  1533. X        return data_str_end >= t.data_str_end;
  1534. X    }
  1535. X    }
  1536. X}
  1537. X
  1538. X// -----------------------------------------------------------------------------
  1539. X
  1540. Xint operator == (const var & t, const char * s)
  1541. X{
  1542. X    var foo = s;
  1543. X    return t == foo;
  1544. X}
  1545. X
  1546. X
  1547. Xint operator != (const var & t, const char * s)
  1548. X{
  1549. X    var foo = s;
  1550. X    return t != foo;
  1551. X}
  1552. X
  1553. X
  1554. Xint operator < (const var & t, const char * s)
  1555. X{
  1556. X    var foo = s;
  1557. X    return t < foo;
  1558. X}
  1559. X
  1560. X
  1561. Xint operator > (const var & t, const char * s)
  1562. X{
  1563. X    var foo = s;
  1564. X    return t > foo;
  1565. X}
  1566. X
  1567. X
  1568. Xint operator <= (const var & t, const char * s)
  1569. X{
  1570. X    var foo = s;
  1571. X    return t <= foo;
  1572. X}
  1573. X
  1574. X
  1575. Xint operator >= (const var & t, const char * s)
  1576. X{
  1577. X    var foo = s;
  1578. X    return t >= foo;
  1579. X}
  1580. X
  1581. X
  1582. Xint operator == (const char * s, const var & t)
  1583. X{
  1584. X    var foo = s;
  1585. X    return foo == t;
  1586. X}
  1587. X
  1588. X
  1589. Xint operator != (const char * s, const var & t)
  1590. X{
  1591. X    var foo = s;
  1592. X    return foo != t;
  1593. X}
  1594. X
  1595. X
  1596. Xint operator < (const char * s, const var & t)
  1597. X{
  1598. X    var foo = s;
  1599. X    return foo < t;
  1600. X}
  1601. X
  1602. X
  1603. Xint operator > (const char * s, const var & t)
  1604. X{
  1605. X    var foo = s;
  1606. X    return foo > t;
  1607. X}
  1608. X
  1609. X
  1610. Xint operator <= (const char * s, const var & t)
  1611. X{
  1612. X    var foo = s;
  1613. X    return foo <= t;
  1614. X}
  1615. X
  1616. X
  1617. Xint operator >= (const char * s, const var & t)
  1618. X{
  1619. X    var foo = s;
  1620. X    return foo >= t;
  1621. X}
  1622. X
  1623. X// -----------------------------------------------------------------------------
  1624. X
  1625. Xint operator == (const var & t, const double d)
  1626. X{
  1627. X    return (double) t == d;
  1628. X}
  1629. X
  1630. X
  1631. Xint operator != (const var & t, const double d)
  1632. X{
  1633. X    return (double) t != d;
  1634. X}
  1635. X
  1636. X
  1637. Xint operator < (const var & t, const double d)
  1638. X{
  1639. X    return (double) t < d;
  1640. X}
  1641. X
  1642. X
  1643. Xint operator > (const var & t, const double d)
  1644. X{
  1645. X    return (double) t > d;
  1646. X}
  1647. X
  1648. X
  1649. Xint operator <= (const var & t, const double d)
  1650. X{
  1651. X    return (double) t <= d;
  1652. X}
  1653. X
  1654. X
  1655. Xint operator >= (const var & t, const double d)
  1656. X{
  1657. X    return (double) t >= d;
  1658. X}
  1659. X
  1660. X
  1661. Xint operator == (const double d, const var & t)
  1662. X{
  1663. X    return d == (double) t;
  1664. X}
  1665. X
  1666. X
  1667. Xint operator != (const double d, const var & t)
  1668. X{
  1669. X    return d != (double) t;
  1670. X}
  1671. X
  1672. X
  1673. Xint operator < (const double d, const var & t)
  1674. X{
  1675. X    return d < (double) t;
  1676. X}
  1677. X
  1678. X
  1679. Xint operator > (const double d, const var & t)
  1680. X{
  1681. X    return d > (double) t;
  1682. X}
  1683. X
  1684. X
  1685. Xint operator <= (const double d, const var & t)
  1686. X{
  1687. X    return d <= (double) t;
  1688. X}
  1689. X
  1690. X
  1691. Xint operator >= (const double d, const var & t)
  1692. X{
  1693. X    return d >= (double) t;
  1694. X}
  1695. X
  1696. X// -----------------------------------------------------------------------------
  1697. X
  1698. Xvoid var::null(int index)
  1699. X{
  1700. X    if (index >= data_str_len) {
  1701. X    cerr << "WARNING: " << " - var::null(" << index << ") - the index out of range." << endl;
  1702. X    (*this)[index] = 0;
  1703. X    data_str_end = index;
  1704. X    }
  1705. X    else {
  1706. X    data_str[index] = 0;
  1707. X    data_str_end = index;
  1708. X    }
  1709. X}
  1710. X
  1711. X
  1712. Xvoid var::changesize(int newsize)
  1713. X{
  1714. X    if (newsize > data_str_len) {
  1715. X    char *buf = new char[newsize];
  1716. X    if (data_str) {
  1717. X        strncpy(buf, data_str, data_str_end);
  1718. X        buf[data_str_end] = 0;
  1719. X        delete data_str;
  1720. X    }
  1721. X    else {
  1722. X        *buf = 0;
  1723. X        data_str_end = 0;
  1724. X    }
  1725. X    data_str_len = newsize;
  1726. X    data_str = buf;
  1727. X    }
  1728. X}
  1729. X
  1730. X
  1731. Xint var::length(void) const
  1732. X{
  1733. X    return data_str_end;
  1734. X}
  1735. X
  1736. X
  1737. Xconst char * var::vartype(void) const
  1738. X{
  1739. X    switch (is_numeric) {
  1740. X    case VAR_STRING:
  1741. X        return "VAR_STRING";
  1742. X    case VAR_LONG:
  1743. X        return "VAR_LONG";
  1744. X    case VAR_DOUBLE:
  1745. X        return "VAR_DOUBLE";
  1746. X    }
  1747. X    return "var type unknown";
  1748. X}
  1749. X
  1750. X
  1751. Xvoid var::change_type(const char *ntype)
  1752. X{
  1753. X    if (ntype == NULL) {
  1754. X    return;
  1755. X    }
  1756. X    int index = strlen(ntype);
  1757. X    if (!index) {
  1758. X    return;
  1759. X    }
  1760. X    char *new_type = new char[index + 1];
  1761. X    if (ntype[0] == '(' && ntype[index - 1] == ')') {
  1762. X    strcpy(new_type, &ntype[1]);
  1763. X    index = strlen(new_type) - 1;
  1764. X    if (index <= 0) {
  1765. X        delete new_type;
  1766. X        return;
  1767. X    }
  1768. X    new_type[index] = 0;            // drop parens
  1769. X    }
  1770. X    else {
  1771. X    strcpy(new_type, ntype);
  1772. X    }
  1773. X    if (new_type[index - 1] == ' ') {
  1774. X    new_type[index - 1] = 0;
  1775. X    }
  1776. X    fixed = 1;
  1777. X    if (!strcmp(new_type, "var")) {
  1778. X    is_numeric = numcheck((const char *) *this);
  1779. X    }
  1780. X    else if (!strcmp(new_type, "string")) {
  1781. X    is_numeric = VAR_STRING;
  1782. X    }
  1783. X    else if (!strcmp(new_type, "short")) {
  1784. X    is_numeric = VAR_LONG;
  1785. X    }
  1786. X    else if (!strcmp(new_type, "unsigned short")) {
  1787. X    is_numeric = VAR_LONG;
  1788. X    }
  1789. X    else if (!strcmp(new_type, "int")) {
  1790. X    is_numeric = VAR_LONG;
  1791. X    }
  1792. X    else if (!strcmp(new_type, "unsigned int")) {
  1793. X    is_numeric = VAR_LONG;
  1794. X    }
  1795. X    else if (!strcmp(new_type, "long")) {
  1796. X    is_numeric = VAR_LONG;
  1797. X    }
  1798. X    else if (!strcmp(new_type, "unsigned long")) {
  1799. X    is_numeric = VAR_LONG;
  1800. X    }
  1801. X    else if (!strcmp(new_type, "float")) {
  1802. X    is_numeric = VAR_DOUBLE;
  1803. X    }
  1804. X    else if (!strcmp(new_type, "double")) {
  1805. X    is_numeric = VAR_DOUBLE;
  1806. X    }
  1807. X    else {
  1808. X    cerr << "WARNING: " << " - change_type(" << new_type << ") - unrecognized type name." << endl;
  1809. X    }
  1810. X    delete new_type;
  1811. X}
  1812. X
  1813. X
  1814. Xint var::is_string(void) const
  1815. X{
  1816. X    return is_numeric == VAR_STRING;
  1817. X}
  1818. X
  1819. X
  1820. Xint var::is_double(void) const
  1821. X{
  1822. X    return is_numeric == VAR_DOUBLE;
  1823. X}
  1824. X
  1825. X
  1826. Xint var::is_long(void) const
  1827. X{
  1828. X    return is_numeric == VAR_LONG;
  1829. X}
  1830. X
  1831. X
  1832. Xint var::strchr(const char ch) const
  1833. X{
  1834. X    for (int i = 0; i < data_str_end; ++i) {
  1835. X    if (data_str[i] == ch) {
  1836. X        return i;
  1837. X    }
  1838. X    }
  1839. X    return -1;
  1840. X}
  1841. X
  1842. X
  1843. Xint var::strrchr(const char ch) const
  1844. X{
  1845. X    for (int i = data_str_end - 1; i >= 0; --i) {
  1846. X    if (data_str[i] == ch) {
  1847. X        return i;
  1848. X    }
  1849. X    }
  1850. X    return -1;
  1851. X}
  1852. X
  1853. X
  1854. Xvar & var::concat(const var & str)
  1855. X{
  1856. X    // concatenate strings
  1857. X    int new_data_str_end = data_str_end + str.data_str_end;
  1858. X    if (new_data_str_end >= data_str_len) {
  1859. X    var add;
  1860. X    add.data_str_len = data_str_len + str.data_str_len + VAR_PAD_SIZE;
  1861. X    add.data_str_end = new_data_str_end;
  1862. X    add.data_str = new char[add.data_str_len];
  1863. X    strcpy(add.data_str, data_str);
  1864. X    strcpy((add.data_str) + data_str_end, str.data_str);
  1865. X    *this = add;
  1866. X    }
  1867. X    else {
  1868. X    strcpy(data_str + data_str_end, str.data_str);
  1869. X    data_str_end += str.data_str_end;
  1870. X    }
  1871. X    return *this;
  1872. X}
  1873. X
  1874. X
  1875. Xvar & var::format(const char * fmt)
  1876. X{
  1877. X    if (format_str
  1878. X    && format_str != DEFAULT_STRING_FORMAT
  1879. X    && format_str != DEFAULT_INT_FORMAT
  1880. X    && format_str != DEFAULT_UINT_FORMAT
  1881. X    && format_str != DEFAULT_LONG_FORMAT
  1882. X    && format_str != DEFAULT_ULONG_FORMAT
  1883. X    && format_str != DEFAULT_DOUBLE_FORMAT) {
  1884. X        delete format_str;
  1885. X    }
  1886. X    if (fmt) {
  1887. X    format_str = new char[strlen(fmt) + 1];
  1888. X    strcpy(format_str, fmt);
  1889. X    }
  1890. X    else {
  1891. X    format_str = NULL;
  1892. X    }
  1893. X    return *this;
  1894. X}
  1895. X
  1896. X
  1897. Xint var::numcheck(const char * str) const
  1898. X{
  1899. X    if (!str || !*str) {
  1900. X    return VAR_STRING;        // assume a string
  1901. X    }
  1902. X    char *ptr = (char *) str;
  1903. X    int nc = VAR_LONG;            // assume a signed long
  1904. X    int decimal_yet = 0;
  1905. X    if (*ptr == '.' && *(ptr + 1)) {
  1906. X    nc = VAR_DOUBLE;        // floating point number
  1907. X    decimal_yet = 1;
  1908. X    ++ptr;
  1909. X    }
  1910. X    else if (*ptr == '-' && *(ptr + 1)) {
  1911. X    // skip optional sign char
  1912. X    ++ptr;
  1913. X    }
  1914. X    while (*ptr) {
  1915. X    if (*ptr == '.' && !decimal_yet) {
  1916. X        decimal_yet = 1;
  1917. X        nc = VAR_DOUBLE;        // assume a double
  1918. X    }
  1919. X    else if (!isdigit(*ptr)) {
  1920. X        return VAR_STRING;        // nope.. got a string
  1921. X    }
  1922. X    ++ptr;
  1923. X    }
  1924. X    return nc;
  1925. X}
  1926. X
  1927. X// -----------------------------------------------------------------------------
  1928. X
  1929. Xint var::save_it(const int save_flag)
  1930. X{
  1931. X    int s = var::save_me;
  1932. X    var::save_me = save_flag;
  1933. X    return s;
  1934. X}
  1935. X
  1936. X// -----------------------------------------------------------------------------
  1937. X
  1938. Xostream & operator << (ostream &out, const var &d)
  1939. X{
  1940. X    d.print(out);
  1941. X    return out;
  1942. X}
  1943. X
  1944. X
  1945. Xvoid var::print(ostream &out) const
  1946. X{
  1947. X    // NOTE: the "read()" function requires a newline to appear after the last quote.
  1948. X    // I assume that this newline was appropriately output by the var class user.
  1949. X    if (!format_str || (format_str && *format_str == 0)) {
  1950. X    out << "var OBJECT: {"
  1951. X        << Inc << "fixed        = " << fixed
  1952. X        << Tab << "is_numeric   = " << is_numeric
  1953. X        << Tab << "data_str_len = " << data_str_len
  1954. X        << Tab << "data_str_end = " << data_str_end
  1955. X        << Tab << "data_str     = '" << data_str << "'"
  1956. X        << Tab << "format_str   = '" << format_str << "'"
  1957. X        << Dec << "}" << endl;
  1958. X    }
  1959. X    else {
  1960. X    // we need to use the specified format string for output
  1961. X    int len = length() + 1;
  1962. X    char *outbuf = new char[2048];
  1963. X    char *fptr = format_str;
  1964. X    while (*fptr) {
  1965. X        if (*fptr != '%' && *fptr != '\\') {
  1966. X        out << *fptr;
  1967. X        ++fptr;
  1968. X        }
  1969. X        else if (*fptr == '\\') {
  1970. X        switch (*(fptr + 1)) {
  1971. X            case 'n':
  1972. X            cout << '\n';
  1973. X            break;
  1974. X            case 't':
  1975. X            cout << '\t';
  1976. X            break;
  1977. X            case 'v':
  1978. X            cout << '\v';
  1979. X            break;
  1980. X            case 'b':
  1981. X            cout << '\b';
  1982. X            break;
  1983. X            case 'r':
  1984. X            cout << '\r';
  1985. X            break;
  1986. X            case 'f':
  1987. X            cout << '\f';
  1988. X            break;
  1989. X            case 'a':
  1990. X            cout << '\007';
  1991. X            break;
  1992. X            case '\\':
  1993. X            cout << '\\';
  1994. X            break;
  1995. X            case '?':
  1996. X            cout << '\?';
  1997. X            break;
  1998. X            case '\'':
  1999. X            cout << '\'';
  2000. X            break;
  2001. X            case '\"':
  2002. X            cout << '\"';
  2003. X            break;
  2004. X            default:
  2005. X            cout << *(fptr + 1);
  2006. X        }
  2007. X        fptr += 2;
  2008. X        }
  2009. X        else {
  2010. X        // Hmmm.. we need to do some special formatting
  2011. X        // first extract this printf-style format string
  2012. X        char smallfmtstr[128];
  2013. X        char *smptr = smallfmtstr;
  2014. X        *smptr = 0;
  2015. X        if (*(fptr + 1) == '%') {
  2016. X            strcpy(outbuf, "%");
  2017. X            fptr += 2;
  2018. X        }
  2019. X        else {
  2020. X            while (*fptr) {
  2021. X            *smptr = *fptr++;
  2022. X            *(smptr + 1) = 0;
  2023. X            // integer
  2024. X            if (*smptr == 'd') {
  2025. X                sprintf(outbuf, smallfmtstr, (int) *this);
  2026. X                break;
  2027. X            }
  2028. X            // unsigned integer
  2029. X            if (*smptr == 'o' || *smptr == 'u' || *smptr == 'x' || *smptr == 'X') {
  2030. X                sprintf(outbuf, smallfmtstr, (unsigned int) *this);
  2031. X                break;
  2032. X            }
  2033. X            // float or double
  2034. X            if (*smptr == 'f' || *smptr == 'e' || *smptr == 'E' || *smptr == 'g' || *smptr == 'G') {
  2035. X                sprintf(outbuf, smallfmtstr, (double) *this);
  2036. X                break;
  2037. X            }
  2038. X            // character
  2039. X            if (*smptr == 'c') {
  2040. X                if (!strcmp(vartype(), "VAR_STRING")) {
  2041. X                const char *tmp = (const char *) (*this);
  2042. X                sprintf(outbuf, smallfmtstr, tmp[0]);
  2043. X                }
  2044. X                else {
  2045. X                sprintf(outbuf, smallfmtstr, (char) ((int) *this));
  2046. X                }
  2047. X                break;
  2048. X            }
  2049. X            // string
  2050. X            if (*smptr == 's') {
  2051. X                sprintf(outbuf, smallfmtstr, (const char *) *this);
  2052. X                break;
  2053. X            }
  2054. X            ++smptr;
  2055. X            }
  2056. X        }
  2057. X        out << outbuf;
  2058. X        }
  2059. X    }
  2060. X    out << flush;
  2061. X    delete outbuf;
  2062. X    }
  2063. X}
  2064. X
  2065. X
  2066. Xistream & operator >> (istream &in, var &d)
  2067. X{
  2068. X    d.read(in);
  2069. X    return in;
  2070. X}
  2071. X
  2072. X
  2073. Xvoid var::read(istream &in)
  2074. X{
  2075. X    // input the same format as was created by the output operator
  2076. X    char buf1[4096];
  2077. X    char buf2[4096];
  2078. X    if (!format_str || (format_str && *format_str == 0)) {
  2079. X    look_for(in, '{');
  2080. X    look_for(in, '=');
  2081. X    in >> fixed;
  2082. X    look_for(in, '=');
  2083. X    in >> is_numeric;
  2084. X    look_for(in, '=');
  2085. X    in >> data_str_len;
  2086. X    look_for(in, '=');
  2087. X    in >> data_str_end;
  2088. X    look_for(in, '=');
  2089. X    scan_string(in, buf1, sizeof(buf1));
  2090. X    look_for(in, '=');
  2091. X    scan_string(in, buf2, sizeof(buf2));
  2092. X    look_for(in, '}');
  2093. X    *this = buf1;
  2094. X    format(buf2);
  2095. X    }
  2096. X    else {
  2097. X    // LEE: need to add input/output formatting capabilities
  2098. X    }
  2099. X}
  2100. X
  2101. END_OF_FILE
  2102.   if test 30983 -ne `wc -c <'var.C'`; then
  2103.     echo shar: \"'var.C'\" unpacked with wrong size!
  2104.   fi
  2105.   # end of 'var.C'
  2106. fi
  2107. echo shar: End of archive 1 \(of 2\).
  2108. cp /dev/null ark1isdone
  2109. MISSING=""
  2110. for I in 1 2 ; do
  2111.     if test ! -f ark${I}isdone ; then
  2112.     MISSING="${MISSING} ${I}"
  2113.     fi
  2114. done
  2115. if test "${MISSING}" = "" ; then
  2116.     echo You have unpacked both archives.
  2117.     rm -f ark[1-9]isdone
  2118. else
  2119.     echo You still must unpack the following archives:
  2120.     echo "        " ${MISSING}
  2121. fi
  2122. exit 0
  2123. exit 0 # Just in case...
  2124.