home *** CD-ROM | disk | FTP | other *** search
/ NetNews Usenet Archive 1992 #18 / NN_1992_18.iso / spool / comp / sources / misc / 3820 < prev    next >
Encoding:
Text File  |  1992-08-21  |  54.1 KB  |  2,130 lines

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