home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 October / usenetsourcesnewsgroupsinfomagicoctober1994disk2.iso / misc / volume34 / fformat / part01 next >
Text File  |  1992-12-12  |  54KB  |  1,853 lines

  1. Newsgroups: comp.sources.misc
  2. From: kirkwood@qucis.queensu.ca (Scott Kirkwood)
  3. Subject:  v34i023:  fformat - C++ class for formatting floating point numbers, Part01/01
  4. Message-ID: <1992Dec13.013912.26325@sparky.imd.sterling.com>
  5. X-Md4-Signature: 203cfd1b465072f658aab68596cdf158
  6. Date: Sun, 13 Dec 1992 01:39:12 GMT
  7. Approved: kent@sparky.imd.sterling.com
  8.  
  9. Submitted-by: kirkwood@qucis.queensu.ca (Scott Kirkwood)
  10. Posting-number: Volume 34, Issue 23
  11. Archive-name: fformat/part01
  12. Environment: C++
  13.  
  14. WHAT IS FFormat?
  15. ================
  16.  
  17. FFormat is a C++ class that is designed to output formatted
  18. floating point numbers (float, double, etc.).  By formatted I mean:
  19.  
  20.    1,234,567.8901 2345
  21.  
  22. FFormat can format to a specified total character width, if the
  23. number doesn't fit it will be divided down until it does and then
  24. the appropriate SI notation will be affixed.  For instance, if
  25. you gave IFormat the number 1234567 and set the width to 6 you would
  26. get:
  27.    1,235K
  28.  
  29. Note that this is just a class to be plugged into your programs.  It
  30. is not a standalone program.
  31.  
  32. WHAT IS TFormat?
  33. ================
  34.  
  35. TFormat is a template version of FFormat (actually a subclass of
  36. FFormat) that is designed to be flexible enough to plug in your own
  37. extended numeric classes.  For instance, I have successfully used
  38. g++'s Integer class with TFormat.  I have also given an example
  39. class (Money) that does the minimum necessary to work with
  40. TFormat (ex. output  $1,234,567.89).
  41.  
  42. OTHER FEATURES
  43. ==============
  44.  
  45. You can change the comma or the space to different characters and the
  46. width of each grouping as well.  For instance you could have
  47.    1234'5678.901,123  
  48.  (here, SetSepWidth(4); SetSep('\''); SetDeciWidth(3); SetDeciSep(',');)
  49.  
  50. You can change the SI postfixes to be different.  For instance, you
  51. might like K=1,024 instead of 1,000.
  52.  
  53. You can toggle whether to use SI postfixes, right adjusting, and
  54. whether separators are used.  You can allow scientific notation (ex.
  55. 1.23e+999). 
  56.  
  57. Can be used with non-floating point values like int, long.
  58.  
  59. EXAMPLE
  60. =======
  61.  
  62.     FFormat FForm;
  63.     cout << FForm.Str(1234567.890123) << endl;
  64.  
  65. outputs -> 1,234,567.8901 23
  66.  
  67. TESTED SYSTEMS
  68. ==============
  69.  
  70. IBM (Borland C++ 3.0, djgcc 2.2.2) and Unix (AT&T CC, GNU g++ 2.2.2).
  71.  
  72. COPYRIGHT
  73. =========
  74.  
  75. This is free software.  Use it and distribute it freely. Please keep
  76. the copyright notices.  Also, please e-mail me for comments, updates,
  77. corrections or bugs.
  78.  
  79. -- CUT HERE -- CUT HERE -- CUT HERE -- CUT HERE -- CUT HERE -- CUT HERE --
  80. #! /bin/sh
  81. # This is a shell archive.  Remove anything before this line, then unpack
  82. # it by saving it into a file and typing "sh file".  To overwrite existing
  83. # files, type "sh file -c".  You can also feed this as standard input via
  84. # unshar, or by typing "sh <file", e.g..  If this archive is complete, you
  85. # will see the following message at the end:
  86. #        "End of archive 1 (of 1)."
  87. # Contents:  MANIFEST Makefile README fformat.C fformat.h make.bor
  88. #   my.out test.C test.bat test.sh
  89. # Wrapped by kirkwood@forelle on Thu Dec 10 13:12:02 1992
  90. PATH=/bin:/usr/bin:/usr/ucb ; export PATH
  91. if test -f 'MANIFEST' -a "${1}" != "-c" ; then 
  92.   echo shar: Will not clobber existing file \"'MANIFEST'\"
  93. else
  94. echo shar: Extracting \"'MANIFEST'\" \(325 characters\)
  95. sed "s/^X//" >'MANIFEST' <<'END_OF_FILE'
  96. XMANIFEST    
  97. XREADME      More information
  98. Xfformat.C   Main C++ routines
  99. Xfformat.h   C++ header file (imbedded help)
  100. XMakefile    UNIX makefile
  101. Xtest.C      Test program 
  102. Xtest.sh     UNIX Bourne shell test program
  103. Xtest.bat    DOS batch test program
  104. Xmake.bor    Borland C++ make file
  105. Xmy.out      My output from test, for comparison
  106. END_OF_FILE
  107. if test 325 -ne `wc -c <'MANIFEST'`; then
  108.     echo shar: \"'MANIFEST'\" unpacked with wrong size!
  109. fi
  110. # end of 'MANIFEST'
  111. fi
  112. if test -f 'Makefile' -a "${1}" != "-c" ; then 
  113.   echo shar: Will not clobber existing file \"'Makefile'\"
  114. else
  115. echo shar: Extracting \"'Makefile'\" \(1337 characters\)
  116. sed "s/^X//" >'Makefile' <<'END_OF_FILE'
  117. X.KEEP_STATE:
  118. X.SUFFIXES: .C .o
  119. X
  120. X# Change to your C++ extensions on your system.
  121. X# (sometimes .c, .cpp, .H, .hpp, .obj)
  122. XC=.C
  123. XH=.h
  124. XO=.o
  125. X
  126. X# Name of your C++ compiler
  127. XCC=g++
  128. X#CC= CC
  129. X#CC=gcc
  130. X
  131. X# Here some defs you might be interested in
  132. X# Do you have "signed" keyword
  133. X#DEFS += -DSIGNED_IMPLEMENTED
  134. X
  135. X# Do you have the long double functions modfl() and fabsl()
  136. X# Note:Some compilers need +a1 compiler switch to allow long doubles.
  137. X#DEFS += -DUSE_LONG_DOUBLE
  138. X
  139. X# Does your compiler support templates?
  140. XDEFS += -DHAVE_TEMPLATES
  141. X
  142. X# Do you want assert statments, or do you trust me :)
  143. X#DEFS += -DNDEBUG
  144. X
  145. X# Want a nice POSIX mu simbol
  146. XDEFS += -DNICE_MU
  147. X
  148. X# Ya want rounding for your template class? 
  149. X# Note: you'll need mod() defined.
  150. X#DEFS += TFORMAT_ROUND
  151. X
  152. XPNAME =fformat  
  153. XFILES.C=$(PNAME)$(C) 
  154. XFILES.H=$(FILES.C:%$(C)=%$(H))
  155. XFILES.O=$(FILES.C:%$(C)=%$(O))
  156. X
  157. X# Use -O for optimizing and -g for debugging
  158. XCFLAGS=-O
  159. X#CFLAGS=-g
  160. X
  161. X$(C)$(O):
  162. X    $(CC) -I$(ARGS_D) $(CFLAGS) $(DEFS) -c $*$(C)
  163. X
  164. X$(FILES.O): $(FILES.C) $(FILES.H)
  165. X    $(CC) -c $(DEFS) $(CFLAGS) $(FILES.C) $(LDFLAGS)
  166. X
  167. Xtest: fformat$(C) fformat$(H)
  168. X    $(CC) $(DEFS) $(CFLAGS) test$(C) fformat$(C) -lm -o fformat
  169. X
  170. Xsample: fformat$(C) fformat$(H)
  171. X    $(CC) $(DEFS) -DSAMPLE_FFORMAT fformat$(C) -o fformat
  172. X
  173. Xclean:
  174. X    rm -f core *$(O) your.out $(PNAME) TAGS
  175. X
  176. X# Dependancy list
  177. X$(PNAME)$(O): $(FILES.C) $(FILES.H)
  178. END_OF_FILE
  179. if test 1337 -ne `wc -c <'Makefile'`; then
  180.     echo shar: \"'Makefile'\" unpacked with wrong size!
  181. fi
  182. # end of 'Makefile'
  183. fi
  184. if test -f 'README' -a "${1}" != "-c" ; then 
  185.   echo shar: Will not clobber existing file \"'README'\"
  186. else
  187. echo shar: Extracting \"'README'\" \(2950 characters\)
  188. sed "s/^X//" >'README' <<'END_OF_FILE'
  189. XFFormat and TFormat C++ classes.
  190. X
  191. XWHAT IS FFormat?
  192. X================
  193. X
  194. XFFormat is a C++ class that is designed to output formatted
  195. Xfloating point numbers (float, double, etc.).  By formatted I mean:
  196. X
  197. X   1,234,567.8901 2345
  198. X
  199. XFFormat can format to a specified total character width, if the
  200. Xnumber doesn't fit it will be divided down until it does and then
  201. Xthe appropriate SI notation will be affixed.  For instance, if
  202. Xyou gave IFormat the number 1234567 and set the width to 6 you would
  203. Xget:
  204. X   1,235K
  205. X
  206. XNote that this is just a class to be plugged into your programs.  It
  207. Xis not a standalone program.
  208. X
  209. XWHAT IS TFormat?
  210. X================
  211. X
  212. XTFormat is a template version of FFormat (actually a subclass of
  213. XFFormat) that is designed to be flexible enough to plug in your own
  214. Xextended numeric classes.  For instance, I have successfully used
  215. Xg++'s Integer class with TFormat.  I have also given an example
  216. Xclass (Money) that does the minimum necessary to work with
  217. XTFormat (ex. output  $1,234,567.89).
  218. X
  219. XOTHER FEATURES
  220. X==============
  221. X
  222. XYou can change the comma or the space to different characters and the
  223. Xwidth of each grouping as well.  For instance you could have
  224. X   1234'5678.901,123  
  225. X (here, SetSepWidth(4); SetSep('\''); SetDeciWidth(3); SetDeciSep(',');)
  226. X
  227. XYou can change the SI postfixes to be different.  For instance, you
  228. Xmight like K=1,024 instead of 1,000.
  229. X
  230. XYou can toggle whether to use SI postfixes, right adjusting, and
  231. Xwhether separators are used.  You can allow scientific notation (ex.
  232. X1.23e+999). 
  233. X
  234. XCan be used with non-floating point values like int, long.
  235. X
  236. XSee fformat.h for more information.
  237. X
  238. XTESTING
  239. X=======
  240. X
  241. XUNIX
  242. X====
  243. X
  244. X  Edit the Makefile for either CC or g++ (g++ by default).
  245. X  Run the Borne shell "test.sh" which will compile and run the
  246. X  demo program.  The shell also runs "diff" to see if your output
  247. X  is identical with my output.
  248. X
  249. XDOS
  250. X===
  251. X
  252. XRename all the .c files to .cc (or .cpp or whatever your standard is).
  253. X
  254. X  Borland
  255. X  -------
  256. X  Either edit the file "make.bor" or open a new project and add the
  257. X  two (renamed) files to the project list.  Press F9 to make (as usual).
  258. X   -or-
  259. X  If you edited the file "make.bor" then run "make -f make.bor".
  260. X
  261. X  GCC
  262. X  ---
  263. X  Edit the file "makefile".  Uncomment "CC=gcc" change the extension
  264. X  to "C=.cc" and run "make test".
  265. X  Edit the file "test.bat" so that it will run go32.
  266. X
  267. X  Both
  268. X  ----
  269. X  Run "test.bat"
  270. X
  271. XEXAMPLE
  272. X=======
  273. X
  274. X    FFormat FForm;
  275. X    cout << FForm.Str(1234567.890123) << endl;
  276. X
  277. Xoutputs -> 1,234,567.8901 23
  278. X
  279. XTESTED SYSTEMS
  280. X==============
  281. X
  282. XIBM (Borland C++ 3.0, djgcc 2.2.2) and Unix (AT&T CC, GNU g++ 2.2.2).
  283. X
  284. XCOPYRIGHT
  285. X=========
  286. X
  287. XThis is free software.  Use it and distribute it freely. Please keep
  288. Xthe copyright notices.  Also, please e-mail me for comments, updates,
  289. Xcorrections or bugs.
  290. X
  291. XAUTHOR / ADDRESS
  292. X================
  293. X
  294. XScott Kirkwood : kirkwood@qucis.queensu.ca
  295. XVoice phone: (613) 531-2674
  296. XGraduate Studies - Computer Information Science
  297. XQueens University
  298. XKingston, CANADA
  299. END_OF_FILE
  300. if test 2950 -ne `wc -c <'README'`; then
  301.     echo shar: \"'README'\" unpacked with wrong size!
  302. fi
  303. # end of 'README'
  304. fi
  305. if test -f 'fformat.C' -a "${1}" != "-c" ; then 
  306.   echo shar: Will not clobber existing file \"'fformat.C'\"
  307. else
  308. echo shar: Extracting \"'fformat.C'\" \(12475 characters\)
  309. sed "s/^X//" >'fformat.C' <<'END_OF_FILE'
  310. X// Copyright (C) 1992 Scott Kirkwood (Queen's University, Ontario, Canada)
  311. X// Voice phone : (613) 531-2674, internet: kirkwood@qucis.queensu.ca
  312. X// This program is given as freeware with no warantees.  Not liable for
  313. X// any loss or damage resulting from this code.  Please acknowledge authorship.
  314. X// Note: Tabs in are size 4
  315. X
  316. X#include "fformat.h"
  317. X#include "assert.h"
  318. X#include <iostream.h>
  319. X#include <string.h>
  320. X#include <math.h>
  321. X#include <ctype.h>
  322. X#include <values.h>
  323. X#include <stdlib.h>
  324. X
  325. X#ifndef USE_LONG_DOUBLE
  326. X#define fabsl fabs
  327. X#define modfl modf
  328. X#endif
  329. X
  330. X// Define statics.
  331. X// Mega, Giga, Tera, Penta?, Exa
  332. Xchar FFormat::ext[] = {' ','K', 'M', 'G',  'T',  'P',  'E'};
  333. Xld FFormat::exp[]    = {1, 1E3, 1E6, 1E9, 1E12, 1E15, 1E18};
  334. X// Milli, Micro, Nano, Pico, Femto, Atto
  335. X#ifdef NICE_MU
  336. X#    ifdef __MSDOS__
  337. X        char FFormat::txe[] = {' ','m', 230, 'n',  'p',  'f',  'a'};
  338. X#    else
  339. X        char FFormat::txe[] = {' ','m', 181, 'n',  'p',  'f',  'a'};
  340. X#    endif
  341. X#else
  342. X    char FFormat::txe[] = {' ','m', 'u', 'n',  'p',  'f',  'a'};
  343. X#endif
  344. Xld FFormat::pxe[]    = {1,1E-3,1E-6,1E-9,1E-12,1E-15,1E-18};
  345. X
  346. X// ============================================================
  347. X// Author      : Scott Kirkwood
  348. X// Date        : Mon Nov  2 1992
  349. X//
  350. X// Prototype   : FFormat.h
  351. X// Description :
  352. X// Constructor, sets the variables to the defaults.
  353. X
  354. XFFormat::FFormat()
  355. X{
  356. X    putseps      = 1; // Should we use a separator
  357. X    width        = 0; // Width to output from 0, 2-  0=infinity
  358. X    use_si       = 1;
  359. X    right_adjust = 1;
  360. X    sep          = ',';
  361. X    sep_width    = 3;
  362. X    deci_sep     = ' ';
  363. X    deci_width   = 4;
  364. X    precision    = 9;
  365. X    work         = 0;
  366. X    worklen      = 0;
  367. X    allowexp     = 0;
  368. X    nodeci       = 0;
  369. X}
  370. X
  371. X// ============================================================
  372. X// Author      : Scott Kirkwood
  373. X// Date        : Mon Nov  2 1992
  374. X//
  375. X// Prototype   : format.h
  376. X// Description :
  377. X// Main routine, handles output of doubles.
  378. X// Note: setting width to anything but 0 causes a big speed penalty.
  379. Xconst char *FFormat::Str(ld num) {
  380. X    int as = 0;
  381. X    int sa = 0;
  382. X    int intlen; // Length of integer part
  383. X    int decilen; // Length of decimal part
  384. X    int otherlen; // everthing else (except \0)
  385. X    int total_len; // Length with commas dots and \0
  386. X    char *str;
  387. X    ld tnum = num;
  388. X    int tprecision   = precision;
  389. X    int tnodeci      = nodeci;
  390. X
  391. X    do {
  392. X        str = itoa(num);
  393. X        getinfo(str, intlen, decilen, otherlen);
  394. X        total_len = estimate_length(intlen, decilen, otherlen);
  395. X        if (as || sa)
  396. X            total_len++;
  397. X        if (width && total_len - 1 > width) {
  398. X            if (fabsl(num) >= 1) { // big number
  399. X                if (!nodeci) {
  400. X                    delete str;
  401. X                    int xtralen = decilen;
  402. X                    if (deci_width)
  403. X                        xtralen += (xtralen - 1) / deci_width;
  404. X
  405. X                    if (width >= total_len - xtralen) {
  406. X                        precision = width - intlen - otherlen;
  407. X                        if (sep_width)
  408. X                            precision -= (intlen - 1) / sep_width;
  409. X                        if (deci_width)
  410. X                            precision -= (precision - 1) / deci_width;
  411. X                        if (precision < 0) {
  412. X                            precision = 0;
  413. X                            nodeci = 1;
  414. X                        }
  415. X                    }
  416. X                    else {
  417. X                        precision = 0;
  418. X                        nodeci = 1;
  419. X                    }
  420. X                }
  421. X                else if (use_si && !allowexp && as < 6) {
  422. X                    delete str;
  423. X                    num = tnum / exp[++as];
  424. X                }
  425. X                else
  426. X                    break;
  427. X            }
  428. X            else { // number is small
  429. X                // because of the way "precision" works we need to know
  430. X                // number of zeros between the point and the 1st num
  431. X                int leadingzeroes = 0;
  432. X                char *p = str;
  433. X                while (*p && *p != '.')
  434. X                    p++;
  435. X                p++;
  436. X                while (*p && *p++ == '0')
  437. X                    leadingzeroes++;
  438. X
  439. X                if (deci_width)
  440. X                    decilen += (decilen - 1) / deci_width;
  441. X                
  442. X                if (width - leadingzeroes > total_len - decilen) {
  443. X                    precision = decilen - leadingzeroes -
  444. X                        (total_len - width);
  445. X                    delete str;
  446. X                }
  447. X                else if (use_si && !allowexp && sa < 6) {
  448. X                    delete str;
  449. X                    num = tnum / pxe[++sa];
  450. X                }
  451. X                else
  452. X                    break;
  453. X            }
  454. X        }
  455. X    } while (width && total_len - 1 > width);
  456. X    if (width >= total_len - 1) {
  457. X        total_len = width + 1;
  458. X    }
  459. X    if (!work || total_len > worklen) {
  460. X        if (work)
  461. X            delete work;
  462. X        work = new char [total_len];
  463. X        worklen = total_len;
  464. X    }
  465. X    PutCommas(str, intlen, work);
  466. X    if (as || sa) {
  467. X        int len = strlen(work);
  468. X
  469. X        work[len]     = as?ext[as]:txe[sa];
  470. X        work[len + 1] = '\0';
  471. X    }
  472. X
  473. X    if (width && right_adjust) {
  474. X        RightAdjust(work, width);
  475. X    }
  476. X    nodeci = tnodeci;
  477. X    precision = tprecision;
  478. X    assert(strlen(work) < worklen);
  479. X
  480. X    return work;
  481. X}
  482. X
  483. X// ============================================================
  484. X// Author      : Scott Kirkwood
  485. X// Date        : Tue Dec  8 1992
  486. X// 
  487. X// Prototype   : fformat.h
  488. X// Description : 
  489. X// I'm using ostrstream to handle the itoa() function.  You 
  490. X// could use you own (faster) routine if you'd like.
  491. X
  492. Xchar *FFormat::itoa(ld num) {
  493. X    ostrstream mys; // Dynamically allocated string.
  494. X    char *str;
  495. X
  496. X    if (!allowexp) {
  497. X        mys.setf(ios::fixed);
  498. X    }
  499. X    else {
  500. X        mys.setf(ios::scientific);
  501. X    }
  502. X    mys.precision(precision);
  503. X    if (nodeci) { // compensate for lack of rounding
  504. X        if (modfl(num, &num) >= .5)
  505. X            num += 1;
  506. X    }
  507. X    mys.setf(0, ios::showpoint); // no trailing zeroes or unnecessary points
  508. X    mys << num;
  509. X    mys << ends;
  510. X
  511. X    str = mys.str();
  512. X    if (!allowexp && str && strchr(str, '.')) {
  513. X        // Fix bug in iostream!
  514. X        char *p = str + strlen(str) - 1;
  515. X        while (*p == '0') {
  516. X            *p-- = '\0'; // kill off trailing 000.
  517. X        }
  518. X        if (*p == '.')
  519. X            *p = '\0';
  520. X    }
  521. X    return str;
  522. X}
  523. X
  524. X
  525. X// ============================================================
  526. X// Author      : Scott Kirkwood
  527. X// Date        : Tue Dec  8 1992
  528. X// 
  529. X// Prototype   : fformat.h
  530. X// Description : 
  531. X// Gets information about the string.  
  532. X// PS. Also zaps any trailing 00000 after the dot.
  533. X// Examples
  534. X// Num     -123456.789
  535. X//         ^
  536. X//         p      intlen=6,decilen=3,prelen=1,otherlen=2
  537. X//
  538. X// Num     123456
  539. X//         ^
  540. X//         p      intlen=6,decilen=0,prelen=0,otherlen=0;
  541. X//
  542. X// Num     123456.789E23
  543. X//         ^
  544. X//         p      intlen=6,decilen=3,prelen=0,otherlen=4
  545. Xvoid FFormat::getinfo(char *p, int &intlen, int &decilen,
  546. X    int &otherlen)
  547. X{
  548. X
  549. X    intlen = decilen = otherlen = 0;
  550. X    // Skip over - or + or spaces?
  551. X
  552. X    while (*p && !isdigit(*p)) {
  553. X        p++;
  554. X        otherlen++;
  555. X    }
  556. X
  557. X    while (*p && isdigit(*p)) {
  558. X        intlen++;
  559. X        p++;
  560. X    }
  561. X    if (*p == '.' && *(p + 1)) {
  562. X        otherlen++; // Count dot
  563. X        p++;
  564. X        while (*p && isdigit(*p)) {
  565. X            decilen++;
  566. X            p++;
  567. X        }
  568. X    }
  569. X    while (*p) {
  570. X        p++;
  571. X        otherlen++;
  572. X    }
  573. X}
  574. X
  575. X// ============================================================
  576. X// Author      : Scott Kirkwood
  577. X// Date        : Mon Nov  2 1992
  578. X//
  579. X// Prototype   : FFormat.h
  580. X// Description :
  581. X// Right adjust the string to the width specified.  Fill with spaces
  582. X// on the left.
  583. Xvoid FFormat::RightAdjust(char *str, int width)
  584. X{
  585. X    int len = strlen(str);
  586. X    if (len >= width)
  587. X        return;
  588. X
  589. X    register char *p = str + len;
  590. X    register char *g = p + (width - len);
  591. X    int spaces = width - len;
  592. X    len++;
  593. X    while (len--) {
  594. X        *g-- = *p--;
  595. X    }
  596. X    while (spaces--) {
  597. X        *g-- = ' ';
  598. X    }
  599. X}
  600. X
  601. X// ============================================================
  602. X// Author      : Scott Kirkwood
  603. X// Date        : Tue Dec  8 1992
  604. X// 
  605. X// Prototype   : fformat.h
  606. X// Description : 
  607. X// Make an exact estimate of the total length required to fit the
  608. X// string including the trailing '\0'.
  609. X
  610. Xint FFormat::estimate_length(int intlen, int decilen, int otherlen) {
  611. X    int len;
  612. X
  613. X    len = intlen + otherlen + 1;
  614. X    if (sep_width && putseps)
  615. X        len += (intlen - 1) / sep_width;
  616. X
  617. X    if (!nodeci) {
  618. X        len += decilen;
  619. X        if (deci_width && putseps)
  620. X            len += (decilen - 1) / deci_width;
  621. X    }
  622. X    else if (decilen)
  623. X        len--; // chop off '.'
  624. X
  625. X    return len;
  626. X}
  627. X
  628. X// ============================================================
  629. X// Author      : Scott Kirkwood
  630. X// Date        : Mon Nov  2 1992
  631. X//
  632. X// Prototype   : FFormat.h
  633. X// Description :
  634. X// Put commas etc. in the proper places.
  635. X// Work points to some location inside a string that is large
  636. X// enough to hold the final output.
  637. X// Example
  638. X//    123456.890123E123    ????????????????????
  639. X//         ^ ^             ^
  640. X//       end afterdot     work
  641. X//   After call
  642. X//                         123,456.8901 23E123\0
  643. X// Update: Made PutCommas() delete trailing zeroes that some libraries
  644. X// put in (even when you specify unsetf(showpoint)).
  645. X
  646. Xvoid FFormat::PutCommas(char *from, int intlen, char *to)
  647. X{
  648. X    int count = 0;
  649. X
  650. X    if (!from || !*from || !to)
  651. X        return; // abort, abort!
  652. X
  653. X    while (!isdigit(*from))
  654. X        *to++ = *from++;
  655. X
  656. X    if (putseps)
  657. X        count = sep_width - (intlen % sep_width) + 1;
  658. X    else
  659. X        count = sep_width + 1;
  660. X
  661. X    if (count > sep_width)
  662. X        count = 1;
  663. X    while (*from && intlen--) {
  664. X        *to++ = *from++;
  665. X        if (sep_width && count == sep_width && intlen && putseps) {
  666. X            count = 0;
  667. X            *to++ = sep;
  668. X        }
  669. X        count++;
  670. X    }
  671. X    if (*from == '.') {
  672. X        if (nodeci) {
  673. X            from++;
  674. X            while (*from && isdigit(*from))
  675. X                from++;
  676. X        }
  677. X        else {
  678. X            *to++ = *from++;
  679. X            count = 1;
  680. X
  681. X            while (*from && isdigit(*from)) {
  682. X                *to++ = *from++;
  683. X                if (deci_width && putseps && 
  684. X                    count == deci_width && *from &&
  685. X                    !strchr("EeGg", *from)) {
  686. X                    count = 0;
  687. X                    *to++ = deci_sep;
  688. X                }
  689. X                count++;
  690. X            }
  691. X        }
  692. X    }
  693. X    while (*from) {
  694. X        *to++ = *from++;
  695. X    }
  696. X    *to = '\0';
  697. X}
  698. X
  699. X
  700. X// ============================================================
  701. X// Author      : Scott Kirkwood
  702. X// Date        : Tue Dec  8 1992
  703. X// 
  704. X// Prototype   : fformat.h
  705. X// Description : 
  706. X// Set the exponent character to c.  Ignored if i is out of range
  707. X// Warning: These values are static and will affect all output by this
  708. X// class! 
  709. Xvoid FFormat::SetSI(int i, char c) {
  710. X    if (i > 0 && i < 7) 
  711. X        ext[i] = c;
  712. X}
  713. X
  714. X// ============================================================
  715. X// Author      : Scott Kirkwood
  716. X// Date        : Tue Dec  8 1992
  717. X// 
  718. X// Prototype   : fformat.h
  719. X// Description : 
  720. X// Set the exponent value to val.  Ignored if i is out of range.
  721. X// Warning: These values are static and will affect all output by this
  722. X// class! 
  723. Xvoid FFormat::SetSI(int i, ld val) {
  724. X    if (i > 0 && i < 7)
  725. X        exp[i] = val;
  726. X}
  727. X
  728. X// ============================================================
  729. X// Author      : Scott Kirkwood
  730. X// Date        : Tue Dec  8 1992
  731. X// 
  732. X// Prototype   : fformat.h
  733. X// Description : 
  734. X// Set the exponent character to c.  Ignored if i is out of range.
  735. X// Warning: These values are static and will affect all output by this
  736. X// class! 
  737. Xvoid FFormat::SetIS(int i, char c) {
  738. X    if (i > 0 && i < 7)
  739. X        txe[i] = c;
  740. X}
  741. X
  742. X// ============================================================
  743. X// Author      : Scott Kirkwood
  744. X// Date        : Tue Dec  8 1992
  745. X// 
  746. X// Prototype   : fformat.h
  747. X// Description : 
  748. X// Set the exponent value to val.  Ignored if i is out of range. 
  749. X// Warning: These values are static and will affect all output by this
  750. X// class! 
  751. X
  752. Xvoid FFormat::SetIS(int i, ld val) {
  753. X    if (i > 0 && i < 7)
  754. X        pxe[i] = val;
  755. X}
  756. X
  757. X#ifdef SAMPLE_FFORMAT
  758. X// The following is a rather an example of some of the ways you
  759. X// can use this class.  
  760. X// Inside main() is the simplest way of using FFormat.
  761. X// Inside try_template() is an example using:
  762. X//    Integer class from GNU's C++ library.
  763. X//    Dollar  class defined below.
  764. X#include <iostream.h>
  765. X
  766. Xvoid try_template();
  767. X
  768. Xint main() {
  769. X    FFormat FForm;
  770. X    double dbl = 123456.7890;
  771. X
  772. X    cout << "Standard format     : " << FForm.Str(dbl) << endl;
  773. X    try_template();
  774. X    return 0;
  775. X}
  776. X
  777. X#ifdef HAVE_TEMPLATES
  778. X#ifdef __GNUC__
  779. X#include <Integer.h>
  780. Xvoid try_template() {
  781. X    const num_width = 33;
  782. X    Integer test;
  783. X    TFormat<Integer> IForm; // Hey man, were using the Integer class!
  784. X    
  785. X    test = 1;
  786. X    for (int i = 0; i < num_width; i++) {
  787. X        test *= 10;
  788. X        test += (i + 2) % 10;
  789. X    }
  790. X    cout << "Using Template class<Integer>: " << IForm.Str(test) << endl;
  791. X}
  792. X#else
  793. Xclass Dollar { // MINIMAL money class, use as an example only.
  794. X    long money;// 12345 => 123.45
  795. Xpublic: 
  796. X    Dollar() { money = 0L; }
  797. X    Dollar(long v) { money = v; }
  798. X    operator long() const { return money; }
  799. X    friend ostream& operator <<(ostream &o, Dollar &d);
  800. X    friend Dollar operator /(const Dollar &a, const Dollar &b);
  801. X    friend void mod(const Dollar &a, const Dollar &b, Dollar &c);
  802. X    friend long  abs(const Dollar &a);
  803. X    friend void operator +=(Dollar &a, const int i);
  804. X};
  805. XDollar operator /(const Dollar &a, const Dollar &b) {
  806. X    Dollar tmp(a); tmp.money /= b.money; return tmp;
  807. X}
  808. Xvoid mod(const Dollar &a, const Dollar &b, Dollar &c) {
  809. X    c.money = a.money % b.money;
  810. X}
  811. Xlong  abs(const Dollar &a) {
  812. X    return (a.money > 0)?a.money:-a.money;
  813. X}
  814. Xvoid operator +=(Dollar &a, const int i) {
  815. X    a.money += i; 
  816. X}
  817. Xostream& operator <<(ostream &o, Dollar &d) {
  818. X    return o << '$' << d.money / 100 << '.' << d.money % 100;
  819. X}
  820. X
  821. Xvoid try_template() {
  822. X    TFormat<Dollar> DForm;
  823. X    Dollar money(12345678L);
  824. X
  825. X    cout << "Using Template class: " << DForm.Str(money) << endl;
  826. X}
  827. X#endif
  828. X#else
  829. Xvoid try_template() { } // Nothing....
  830. X#endif /* HAVE_TEMPLATE */
  831. X#endif
  832. END_OF_FILE
  833. if test 12475 -ne `wc -c <'fformat.C'`; then
  834.     echo shar: \"'fformat.C'\" unpacked with wrong size!
  835. fi
  836. # end of 'fformat.C'
  837. fi
  838. if test -f 'fformat.h' -a "${1}" != "-c" ; then 
  839.   echo shar: Will not clobber existing file \"'fformat.h'\"
  840. else
  841. echo shar: Extracting \"'fformat.h'\" \(11858 characters\)
  842. sed "s/^X//" >'fformat.h' <<'END_OF_FILE'
  843. X#ifndef _FFORMAT_H
  844. X#define _FFORMAT_H
  845. X
  846. X// Copyright (C) 1992 Scott Kirkwood (Queen's University, Ontario, Canada)
  847. X// Voice phone : (613) 531-2674, internet: kirkwood@qucis.queensu.ca
  848. X// This program is given as freeware with no warantees.  Not liable for
  849. X// any loss or damage resulting from this code.  Please acknowledge authorship.
  850. X// Note: Tabs in are size 4
  851. X
  852. X#include <strstream.h>
  853. X
  854. X#ifdef SIGNED_IMPLEMENTED
  855. X#define SIGNED signed
  856. X#else
  857. X#define SIGNED
  858. X#endif
  859. X
  860. X#ifdef USE_LONG_DOUBLE
  861. Xtype long double ld;
  862. X#else
  863. Xtypedef double ld;
  864. X#endif
  865. X
  866. X// Description
  867. X// ===========
  868. X//
  869. X// FFormat is a C++ class that is designed to output formatted
  870. X// floating point numbers (float, double, etc.).  By formatted I mean:
  871. X//    1,234,567.8901 2345
  872. X//
  873. X// TFormat is a template version of FFormat (actually a subclass of
  874. X// FFormat) that is designed to be flexible enough to plug in your own
  875. X// extended numeric classes.  For instance, I have successfully used
  876. X// g++'s Integer class and Fix class.  I have also given a minimal
  877. X// example of a Money class where "Money" uses a long to store its
  878. X// value and divides the value by a 100 to get dollars and cents.  It
  879. X// also show's that FFormat can handle funny leading characters like
  880. X// the dollar sign with no probs. 
  881. X//
  882. X// OTHER FEATURES
  883. X// ==============
  884. X//
  885. X// FFormat can format to a specified total character width, if the
  886. X// number doesn't fit it will be divided down until it does and then
  887. X// the appropriate SI notation will be affixed.  For instance, if
  888. X// you gave IFormat the number 1234567 and set the width to 6 you would
  889. X// get:
  890. X//  1,235K
  891. X//
  892. X// You can change these values if you prefer the computer science
  893. X// K = 1,024, for instance.
  894. X//
  895. X// IFormat will, by default, right adjust number if the ouput is smaller
  896. X// than the width passed.  Where a width of 0 signifies variable width.
  897. X// For instance, here's 123 with a width of 5 (vertical bars for clarity)
  898. X//   |  123|
  899. X//
  900. X// You can toggle whether to use SI postfixes, right adjusting, and
  901. X// whether separators are used.
  902. X//
  903. X// DEFAULTS
  904. X// ========
  905. X// putseps      = true (use the separator characters)
  906. X// width        = 0    (unlimited length of output)
  907. X// use_si       = true (that is, if width set to something)
  908. X// right_adjust = true (numbers are right adjusted)
  909. X// sep          = ','  (comma is integer separator)
  910. X// sep_width    = 3    (123,456 etc.  in groups of 3)
  911. X// deci_sep     = ' '  (space is the fractional part separator)
  912. X// deci_width   = 4    (.1234 5678 etc. in groups of 4)
  913. X// precision    = 0    (unlimited)
  914. X// allowexp     = 0    (do not use exponent notation)
  915. X//
  916. X// By default the postfixes are:
  917. X// Kilo  'K' 1E3       Milli 'm' 1E-3 
  918. X// Mega  'M' 1E6       Micro 'u' 1E-6 (or the mu character)
  919. X// Giga  'G' 1E9       Nano  'n' 1E-9 
  920. X// Tera  'T' 1E12      Pico  'p' 1E-12
  921. X// Penta 'P' 1E15      Femto 'f' 1E-15
  922. X// Exa   'E' 1E18      Atto  'a' 1E-18
  923. X//
  924. X// WIDTH
  925. X// =====
  926. X// When specifying a width to shoot for, FFormat goes into a different
  927. X// mode.  In fact most of the code deals with the problems we get when
  928. X// a width is specified.  Here's a synopsis of what happens.
  929. X// - If the string fits, great.  Right adjust if necessary.
  930. X// else if it doesn't fit then
  931. X//   - If the number is not tiny then
  932. X//     - chop off as many decimal places as needed to make it fit.
  933. X//     - If that doesn't work,
  934. X//       - Divide the number by the minimum SI value to make it fit.
  935. X//   else if the number is tiny (like 1E-10) then
  936. X//     - chop off as many decimal places as needed to fit (but leave 1)
  937. X//     - if that doesn't work,
  938. X//       - Divide the number by the largest SI value (ex. micro) to make
  939. X//         it fit. 
  940. X// 
  941. X// DYNAMIC ALLOCATION
  942. X// ==================
  943. X// The string pointer "work" is dynamically allocated (with new and
  944. X// delete).  You can safely delete work if you need the space, just
  945. X// make sure that work points to NULL before you call Str() again.  
  946. X// If you haven't deleted "work" then the space will be either a)
  947. X// re-used if the new number will fit, or b) deleted and a new (larger)
  948. X// block of memory allocated.  It is better, therefore, to print your
  949. X// large numbers first and work down to your smaller numbers later to
  950. X// prevent heap fragmentation.  Alternatively, use Str(1E100), for instace,
  951. X// to get FFormat to make a lot of space available. 
  952. X//
  953. X// TO DO
  954. X// =====
  955. X// I guess some people would like even more formatting features. Like:
  956. X//   - Aligning numbers at the decimal point.
  957. X//   - Allowing a space between the SI postfix and the numbers.
  958. X//   - Allowing limits with the postfix notation.  i.e. allow the use of
  959. X//     K for 1,000 but not the use of M or higher.
  960. X// - It could be smarter about using exponents.
  961. X// - Could eliminate one or both separators in order to squeeze the
  962. X//   number in the width asked for.
  963. X// - Make it faster.
  964. X// - I wanted to use "locale.h" to figure out the standards for the
  965. X//   system, but I found the functions didn't work very well.  I think
  966. X//   that someone with more experience with these problems should make
  967. X//   a "locale" aware subclass of FFormat. (and send it to me!)
  968. X
  969. Xclass FFormat {
  970. X    protected:
  971. X    int    putseps;      // Should we use a separator
  972. X    int    width;        // Total output width.
  973. X    int    use_si;       // Should we use SI postfix notations?
  974. X    int    right_adjust; // Should we right adjust
  975. X    char   sep;          // Usually a comma
  976. X    short  sep_width;    // Usually three
  977. X    short  deci_width;   // Usually four
  978. X    char   deci_sep;     // Usually a space
  979. X    int    precision;    // Number of digits after the decimal point
  980. X    char   *work;         // Output string, dynamically allocated.
  981. X    int    worklen;      // Size of allocated string
  982. X    int    allowexp;     // allow exponent notation.
  983. X    int    nodeci;       // Don't show past decimal point
  984. X
  985. X    void Show();
  986. X    void SetVars();
  987. X    void getinfo(char *p, int &intlen, int &decilen, int &otherlen);
  988. X    void getinfo(char *p, char *&end, int &intlen,
  989. X        int &decilen, int &otherlen, char *&afterdot);
  990. X    int  estimate_length(int intlen, int decilen, int otherlen);
  991. X    void PutCommas(char *end, int len, char *work);
  992. X    void RightAdjust(char *, int);
  993. Xprotected:
  994. X    static char ext[];
  995. X    static char txe[];
  996. X    static ld exp[];
  997. X    static ld pxe[];
  998. X    char *itoa(ld);      // Make your own itoa...
  999. Xpublic:
  1000. X    FFormat();           // Constructor
  1001. X
  1002. X    const char *Str(SIGNED int num)   { return Str((ld)num); }
  1003. X    const char *Str(SIGNED long num)  { return Str((ld)num); }
  1004. X    const char *Str(unsigned int num) { return Str((ld)num); }
  1005. X    const char *Str(unsigned long num){ return Str((ld)num); }
  1006. X    const char *Str(float num)        { return Str((ld)num); }
  1007. X    const char *Str(char num)         { return Str((ld)num); }
  1008. X#ifdef USE_LONG_DOUBLE
  1009. X    const char *Str(double num)       { return Str((ld)num); }
  1010. X#endif
  1011. X    const char *Str(ld num);
  1012. X    void  SetSepWidth(int i)          { sep_width = i; }
  1013. X    void  SetSep(char ch)             { sep = ch; }
  1014. X    void  SetDeciWidth(int i)         { deci_width = i; }
  1015. X    void  SetDeciSep(char ch)         { deci_sep = ch; }
  1016. X    void  SetWidth(int i)             { width = i; }
  1017. X    void  SetUseSeparators(int i)     { putseps = i; }
  1018. X    void  SetRightAdjust(int i)       { right_adjust = i; }
  1019. X    void  SetUseSI(int i)             { use_si = i; }
  1020. X    void  SetUseExp(int i)            { allowexp = i; }
  1021. X    void  SetPrecision(int i)         { precision = i; }
  1022. X    void  SetSI(int i, char c);       // set big SI character (i=1->'K')
  1023. X    void  SetSI(int i, ld val);       // Set big SI value     (i=1->1E3)
  1024. X    void  SetIS(int i, char c);       // set small SI character (i=1->'m')
  1025. X    void  SetIS(int i, ld val);       // Set small SI value   (i=1->1E-3)
  1026. X
  1027. X    int   SepWidth()                  { return sep_width; }
  1028. X    char  Sep()                       { return sep; }
  1029. X    int   DeciWidth()                 { return deci_width; }
  1030. X    char  DeciSep()                   { return deci_sep; }
  1031. X    int   Width()                     { return width; }
  1032. X    int   UseSeparators()             { return putseps; }
  1033. X    int   RightAdjust()               { return right_adjust; }
  1034. X    int   Precision()                 { return precision; }
  1035. X    int   UseSI()                     { return use_si; }
  1036. X    int   UseExp()                    { return allowexp; }
  1037. X};
  1038. X
  1039. X#ifdef HAVE_TEMPLATES
  1040. X// OK If we have templates, then let's make a template class.
  1041. X// This template class allows you to ADD extra ability to Format.
  1042. X// For instance, I have successfully used TFormat<Integer> from the
  1043. X// GNU library of variable length integers.  The class you are adding
  1044. X// should have (the equivalent of):
  1045. X//
  1046. X//     friend ostream& operator <<(ostream &, const YourClass &)
  1047. X//     friend YourClass operator /(const YourClass, const YourClass)
  1048. X//     friend void mod(const YourClass, const YourClass, YourClass &Result)
  1049. X//     friend int  abs(const YourClass)
  1050. X//     friend void operator +=(YourClass, const int)
  1051. X//     operator int();
  1052. X//
  1053. X// defined and declared.  (Of course you know that it doesn't have to
  1054. X// be declared exactly as above)
  1055. X// My experience is that the entire template definition/declaration
  1056. X// must be included in the header file to work correctly. So here it is...
  1057. X
  1058. Xtemplate <class T>
  1059. Xclass TFormat : public FFormat {
  1060. X    protected:
  1061. X    char *itoa(T);
  1062. Xpublic:
  1063. X    const char *Str(T);
  1064. X};
  1065. X
  1066. X// This is a copy of the code contained in FFormat (pretty much).
  1067. Xtemplate <class T>
  1068. Xconst char *TFormat<T>::Str(T num) {
  1069. X    int as = 0;
  1070. X    int sa = 0;
  1071. X    int intlen; // Length of integer part
  1072. X    int decilen; // Length of decimal part
  1073. X    int otherlen; // everthing else (except \0)
  1074. X    int total_len; // Length with commas dots and \0
  1075. X    char *str;
  1076. X    T tnum = num;
  1077. X    int tprecision   = precision;
  1078. X    int tnodeci      = nodeci;
  1079. X
  1080. X    do {
  1081. X        str = itoa(num);
  1082. X        getinfo(str, intlen, decilen, otherlen);
  1083. X        total_len = estimate_length(intlen, decilen, otherlen);
  1084. X        if (as || sa)
  1085. X            total_len++;
  1086. X        if (width && total_len - 1 > width) {
  1087. X            if (abs(num) >= 1) { // big number
  1088. X                if (!nodeci) {
  1089. X                    delete str;
  1090. X                    int xtralen = decilen;
  1091. X                    if (deci_width)
  1092. X                        xtralen += (xtralen - 1) / deci_width;
  1093. X
  1094. X                    if (width >= total_len - xtralen) {
  1095. X                        precision = width - intlen - otherlen;
  1096. X                        if (sep_width)
  1097. X                            precision -= (intlen - 1) / sep_width;
  1098. X                        if (deci_width)
  1099. X                            precision -= (precision - 1) / deci_width;
  1100. X                        if (precision < 0) {
  1101. X                            precision = 0;
  1102. X                            nodeci = 1;
  1103. X                        }
  1104. X                    }
  1105. X                    else {
  1106. X                        precision = 0;
  1107. X                        nodeci = 1;
  1108. X                    }
  1109. X                }
  1110. X                else if (use_si && as < 6) {
  1111. X                    delete str;
  1112. X                    num = tnum / (T)(exp[++as]);
  1113. X                }
  1114. X                else
  1115. X                    break;
  1116. X            }
  1117. X            else { // number is small
  1118. X                int leadingzeroes = 0;
  1119. X                char *p = str;
  1120. X                while (*p && *p != '.')
  1121. X                    p++;
  1122. X                p++;
  1123. X                while (*p && *p++ == '0')
  1124. X                    leadingzeroes++;
  1125. X
  1126. X                if (deci_width)
  1127. X                    decilen += (decilen - 1) / deci_width;
  1128. X                
  1129. X                if (width - leadingzeroes > total_len - decilen) {
  1130. X                    precision = decilen - leadingzeroes -
  1131. X                        (total_len - width);
  1132. X                    delete str;
  1133. X                }
  1134. X                else if (use_si && sa < 6) {
  1135. X                    delete str;
  1136. X                    num = tnum / (T)(pxe[++sa]);
  1137. X                }
  1138. X                else
  1139. X                    break;
  1140. X            }
  1141. X        }
  1142. X    } while (width && total_len - 1 > width);
  1143. X    if (width >= total_len - 1) {
  1144. X        total_len = width + 1;
  1145. X    }
  1146. X    if (!work || total_len > worklen) {
  1147. X        if (work)
  1148. X            delete work;
  1149. X        work = new char [total_len];
  1150. X        worklen = total_len;
  1151. X    }
  1152. X    PutCommas(str, intlen, work);
  1153. X    if (as || sa) {
  1154. X        int len = strlen(work);
  1155. X
  1156. X        work[len]   = as?ext[as]:txe[sa];
  1157. X        work[len + 1] = '\0';
  1158. X    }
  1159. X
  1160. X    if (width && right_adjust) {
  1161. X        RightAdjust(work, width);
  1162. X    }
  1163. X    nodeci = tnodeci;
  1164. X    precision = tprecision;
  1165. X//    assert(strlen(work) < worklen);
  1166. X
  1167. X    return work;
  1168. X}
  1169. X
  1170. Xtemplate <class T>
  1171. Xchar *TFormat<T>::itoa(T num) {
  1172. X    ostrstream mys; // Dynamically allocated string.
  1173. X    if (!allowexp) {
  1174. X        mys.setf(ios::fixed);
  1175. X    }
  1176. X    else {
  1177. X        mys.setf(ios::scientific);
  1178. X    }
  1179. X    mys.precision(precision);
  1180. X#ifdef TFORMAT_ROUND
  1181. X    if (nodeci) { // compensate for lack of rounding
  1182. X        T result;
  1183. X        mod(num, num, result);
  1184. X        if (10 * result >= 5)
  1185. X            num += 1;
  1186. X    }
  1187. X#endif
  1188. X    mys << num;
  1189. X    mys << ends;
  1190. X    return mys.str();
  1191. X}
  1192. X
  1193. X#endif
  1194. X#endif
  1195. END_OF_FILE
  1196. if test 11858 -ne `wc -c <'fformat.h'`; then
  1197.     echo shar: \"'fformat.h'\" unpacked with wrong size!
  1198. fi
  1199. # end of 'fformat.h'
  1200. fi
  1201. if test -f 'make.bor' -a "${1}" != "-c" ; then 
  1202.   echo shar: Will not clobber existing file \"'make.bor'\"
  1203. else
  1204. echo shar: Extracting \"'make.bor'\" \(1041 characters\)
  1205. sed "s/^X//" >'make.bor' <<'END_OF_FILE'
  1206. X.AUTODEPEND
  1207. X
  1208. X#        *Translator Definitions*
  1209. XCC = bcc +FFORMAT.CFG
  1210. XTASM = TASM
  1211. XTLIB = tlib
  1212. XTLINK = tlink
  1213. XLIBPATH = C:\BC3\LIB
  1214. XINCLUDEPATH = C:\BC3\INCLUDE
  1215. X
  1216. X
  1217. X#        *Implicit Rules*
  1218. X.c.obj:
  1219. X  $(CC) -c {$< }
  1220. X
  1221. X.cpp.obj:
  1222. X  $(CC) -c {$< }
  1223. X
  1224. X#        *List Macros*
  1225. X
  1226. X
  1227. XEXE_dependencies =  \
  1228. X fformat.obj \
  1229. X test.obj
  1230. X
  1231. X#        *Explicit Rules*
  1232. Xfformat.exe: fformat.cfg $(EXE_dependencies)
  1233. X  $(TLINK) /v/x/c/P-/L$(LIBPATH) @&&|
  1234. Xc0s.obj+
  1235. Xfformat.obj+
  1236. Xtest.obj
  1237. Xfformat
  1238. X        # no map file
  1239. Xemu.lib+
  1240. Xmaths.lib+
  1241. Xcs.lib
  1242. X|
  1243. X
  1244. X
  1245. X#        *Individual File Dependencies*
  1246. Xfformat.obj: fformat.cfg fformat.cc 
  1247. X    $(CC) -c fformat.cc
  1248. X
  1249. Xtest.obj: fformat.cfg test.cc 
  1250. X    $(CC) -c test.cc
  1251. X
  1252. X#        *Compiler Configuration File*
  1253. Xfformat.cfg: fformat.mak
  1254. X  copy &&|
  1255. X-v
  1256. X-G
  1257. X-O
  1258. X-Og
  1259. X-Oe
  1260. X-Om
  1261. X-Ov
  1262. X-Ol
  1263. X-Ob
  1264. X-Op
  1265. X-Oi
  1266. X-Z
  1267. X-k-
  1268. X-vi
  1269. X-w-ret
  1270. X-w-nci
  1271. X-w-inl
  1272. X-wpin
  1273. X-wamb
  1274. X-wamp
  1275. X-w-par
  1276. X-wasm
  1277. X-wcln
  1278. X-w-cpt
  1279. X-wdef
  1280. X-w-dup
  1281. X-w-pia
  1282. X-wsig
  1283. X-wnod
  1284. X-w-ill
  1285. X-w-sus
  1286. X-wstv
  1287. X-wucp
  1288. X-wuse
  1289. X-w-ext
  1290. X-w-ias
  1291. X-w-ibc
  1292. X-w-pre
  1293. X-w-nst
  1294. X-I$(INCLUDEPATH)
  1295. X-L$(LIBPATH)
  1296. X-DNICE_MU NDEBUG HAVE_TEMPLATES USE_LONG_DOUBLE SIGNED_IMPLEMENTED TFORMAT_ROUND
  1297. X-P
  1298. X| fformat.cfg
  1299. X
  1300. X
  1301. END_OF_FILE
  1302. if test 1041 -ne `wc -c <'make.bor'`; then
  1303.     echo shar: \"'make.bor'\" unpacked with wrong size!
  1304. fi
  1305. # end of 'make.bor'
  1306. fi
  1307. if test -f 'my.out' -a "${1}" != "-c" ; then 
  1308.   echo shar: Will not clobber existing file \"'my.out'\"
  1309. else
  1310. echo shar: Extracting \"'my.out'\" \(12068 characters\)
  1311. sed "s/^X//" >'my.out' <<'END_OF_FILE'
  1312. XDefault.
  1313. X                    Input    |Unlimited|
  1314. X                        1 -> |1|
  1315. X                       12 -> |12|
  1316. X                      123 -> |123|
  1317. X                    1,234 -> |1,234|
  1318. X                   12,345 -> |12,345|
  1319. X                  123,456 -> |123,456|
  1320. X                1,234,567 -> |1,234,567|
  1321. X               12,345,678 -> |12,345,678|
  1322. X             12,345,678.1 -> |12,345,678.1|
  1323. X   12,345,678.1199 9999 9 -> |12,345,678.1199 9999 9|
  1324. X           12,345,678.123 -> |12,345,678.123|
  1325. X   12,345,678.1233 9999 9 -> |12,345,678.1233 9999 9|
  1326. X        12,345,678.1234 5 -> |12,345,678.1234 5|
  1327. X                       -1 -> |-1|
  1328. X                      -12 -> |-12|
  1329. X                     -123 -> |-123|
  1330. X                   -1,234 -> |-1,234|
  1331. X                  -12,345 -> |-12,345|
  1332. X                 -123,456 -> |-123,456|
  1333. X               -1,234,567 -> |-1,234,567|
  1334. X              -12,345,678 -> |-12,345,678|
  1335. X            -12,345,678.1 -> |-12,345,678.1|
  1336. X  -12,345,678.1199 9999 9 -> |-12,345,678.1199 9999 9|
  1337. X          -12,345,678.123 -> |-12,345,678.123|
  1338. X  -12,345,678.1233 9999 9 -> |-12,345,678.1233 9999 9|
  1339. X       -12,345,678.1234 5 -> |-12,345,678.1234 5|
  1340. X                      9.1 -> |9.1|
  1341. X                     9.12 -> |9.12|
  1342. X                    9.123 -> |9.123|
  1343. X                   9.1234 -> |9.1234|
  1344. X                 9.1234 5 -> |9.1234 5|
  1345. X                      0.1 -> |0.1|
  1346. X                     0.02 -> |0.02|
  1347. X                    0.003 -> |0.003|
  1348. X                   0.0004 -> |0.0004|
  1349. X                 0.0000 5 -> |0.0000 5|
  1350. XDon't use the separators.
  1351. X                    Input    |Unlimited|
  1352. X                        1 -> |1|
  1353. X                       12 -> |12|
  1354. X                      123 -> |123|
  1355. X                    1,234 -> |1234|
  1356. X                   12,345 -> |12345|
  1357. X                  123,456 -> |123456|
  1358. X                1,234,567 -> |1234567|
  1359. X               12,345,678 -> |12345678|
  1360. X             12,345,678.1 -> |12345678.1|
  1361. X   12,345,678.1199 9999 9 -> |12345678.119999999|
  1362. X           12,345,678.123 -> |12345678.123|
  1363. X   12,345,678.1233 9999 9 -> |12345678.123399999|
  1364. X        12,345,678.1234 5 -> |12345678.12345|
  1365. X                       -1 -> |-1|
  1366. X                      -12 -> |-12|
  1367. X                     -123 -> |-123|
  1368. X                   -1,234 -> |-1234|
  1369. X                  -12,345 -> |-12345|
  1370. X                 -123,456 -> |-123456|
  1371. X               -1,234,567 -> |-1234567|
  1372. X              -12,345,678 -> |-12345678|
  1373. X            -12,345,678.1 -> |-12345678.1|
  1374. X  -12,345,678.1199 9999 9 -> |-12345678.119999999|
  1375. X          -12,345,678.123 -> |-12345678.123|
  1376. X  -12,345,678.1233 9999 9 -> |-12345678.123399999|
  1377. X       -12,345,678.1234 5 -> |-12345678.12345|
  1378. X                      9.1 -> |9.1|
  1379. X                     9.12 -> |9.12|
  1380. X                    9.123 -> |9.123|
  1381. X                   9.1234 -> |9.1234|
  1382. X                 9.1234 5 -> |9.12345|
  1383. X                      0.1 -> |0.1|
  1384. X                     0.02 -> |0.02|
  1385. X                    0.003 -> |0.003|
  1386. X                   0.0004 -> |0.0004|
  1387. X                 0.0000 5 -> |0.00005|
  1388. XSet width to 7 and don't right adjust.
  1389. X                    Input    |-------|
  1390. X                        1 -> |1|
  1391. X                       12 -> |12|
  1392. X                      123 -> |123|
  1393. X                    1,234 -> |1,234|
  1394. X                   12,345 -> |12,345|
  1395. X                  123,456 -> |123,456|
  1396. X                1,234,567 -> |1,235K|
  1397. X               12,345,678 -> |12,346K|
  1398. X             12,345,678.1 -> |12,346K|
  1399. X   12,345,678.1199 9999 9 -> |12,346K|
  1400. X           12,345,678.123 -> |12,346K|
  1401. X   12,345,678.1233 9999 9 -> |12,346K|
  1402. X        12,345,678.1234 5 -> |12,346K|
  1403. X                       -1 -> |-1|
  1404. X                      -12 -> |-12|
  1405. X                     -123 -> |-123|
  1406. X                   -1,234 -> |-1,234|
  1407. X                  -12,345 -> |-12,345|
  1408. X                 -123,456 -> |-123K|
  1409. X               -1,234,567 -> |-1,234K|
  1410. X              -12,345,678 -> |-12M|
  1411. X            -12,345,678.1 -> |-12M|
  1412. X  -12,345,678.1199 9999 9 -> |-12M|
  1413. X          -12,345,678.123 -> |-12M|
  1414. X  -12,345,678.1233 9999 9 -> |-12M|
  1415. X       -12,345,678.1234 5 -> |-12M|
  1416. X                      9.1 -> |9.1|
  1417. X                     9.12 -> |9.12|
  1418. X                    9.123 -> |9.123|
  1419. X                   9.1234 -> |9.1234|
  1420. X                 9.1234 5 -> |9.1235|
  1421. X                      0.1 -> |0.1|
  1422. X                     0.02 -> |0.02|
  1423. X                    0.003 -> |0.003|
  1424. X                   0.0004 -> |0.0004|
  1425. X                 0.0000 5 -> |0.05m|
  1426. XSet width to 7 and don't use SI.
  1427. X                    Input    |-------|
  1428. X                        1 -> |      1|
  1429. X                       12 -> |     12|
  1430. X                      123 -> |    123|
  1431. X                    1,234 -> |  1,234|
  1432. X                   12,345 -> | 12,345|
  1433. X                  123,456 -> |123,456|
  1434. X                1,234,567 -> |1,234,567|
  1435. X               12,345,678 -> |12,345,678|
  1436. X             12,345,678.1 -> |12,345,678|
  1437. X   12,345,678.1199 9999 9 -> |12,345,678|
  1438. X           12,345,678.123 -> |12,345,678|
  1439. X   12,345,678.1233 9999 9 -> |12,345,678|
  1440. X        12,345,678.1234 5 -> |12,345,678|
  1441. X                       -1 -> |     -1|
  1442. X                      -12 -> |    -12|
  1443. X                     -123 -> |   -123|
  1444. X                   -1,234 -> | -1,234|
  1445. X                  -12,345 -> |-12,345|
  1446. X                 -123,456 -> |-123,456|
  1447. X               -1,234,567 -> |-1,234,567|
  1448. X              -12,345,678 -> |-12,345,678|
  1449. X            -12,345,678.1 -> |-12,345,678|
  1450. X  -12,345,678.1199 9999 9 -> |-12,345,678|
  1451. X          -12,345,678.123 -> |-12,345,678|
  1452. X  -12,345,678.1233 9999 9 -> |-12,345,678|
  1453. X       -12,345,678.1234 5 -> |-12,345,678|
  1454. X                      9.1 -> |    9.1|
  1455. X                     9.12 -> |   9.12|
  1456. X                    9.123 -> |  9.123|
  1457. X                   9.1234 -> | 9.1234|
  1458. X                 9.1234 5 -> | 9.1235|
  1459. X                      0.1 -> |    0.1|
  1460. X                     0.02 -> |   0.02|
  1461. X                    0.003 -> |  0.003|
  1462. X                   0.0004 -> | 0.0004|
  1463. X                 0.0000 5 -> |0.0000 5|
  1464. XSet separator width to 4 and Sep is a space.
  1465. X                    Input    |Unlimited|
  1466. X                        1 -> |1|
  1467. X                       12 -> |12|
  1468. X                      123 -> |123|
  1469. X                    1,234 -> |1234|
  1470. X                   12,345 -> |1 2345|
  1471. X                  123,456 -> |12 3456|
  1472. X                1,234,567 -> |123 4567|
  1473. X               12,345,678 -> |1234 5678|
  1474. X             12,345,678.1 -> |1234 5678.1|
  1475. X   12,345,678.1199 9999 9 -> |1234 5678.1199 9999 9|
  1476. X           12,345,678.123 -> |1234 5678.123|
  1477. X   12,345,678.1233 9999 9 -> |1234 5678.1233 9999 9|
  1478. X        12,345,678.1234 5 -> |1234 5678.1234 5|
  1479. X                       -1 -> |-1|
  1480. X                      -12 -> |-12|
  1481. X                     -123 -> |-123|
  1482. X                   -1,234 -> |-1234|
  1483. X                  -12,345 -> |-1 2345|
  1484. X                 -123,456 -> |-12 3456|
  1485. X               -1,234,567 -> |-123 4567|
  1486. X              -12,345,678 -> |-1234 5678|
  1487. X            -12,345,678.1 -> |-1234 5678.1|
  1488. X  -12,345,678.1199 9999 9 -> |-1234 5678.1199 9999 9|
  1489. X          -12,345,678.123 -> |-1234 5678.123|
  1490. X  -12,345,678.1233 9999 9 -> |-1234 5678.1233 9999 9|
  1491. X       -12,345,678.1234 5 -> |-1234 5678.1234 5|
  1492. X                      9.1 -> |9.1|
  1493. X                     9.12 -> |9.12|
  1494. X                    9.123 -> |9.123|
  1495. X                   9.1234 -> |9.1234|
  1496. X                 9.1234 5 -> |9.1234 5|
  1497. X                      0.1 -> |0.1|
  1498. X                     0.02 -> |0.02|
  1499. X                    0.003 -> |0.003|
  1500. X                   0.0004 -> |0.0004|
  1501. X                 0.0000 5 -> |0.0000 5|
  1502. XNormal SepWidth, but Width set to 5
  1503. X                    Input    |-----|
  1504. X                        1 -> |    1|
  1505. X                       12 -> |   12|
  1506. X                      123 -> |  123|
  1507. X                    1,234 -> |1,234|
  1508. X                   12,345 -> |  12K|
  1509. X                  123,456 -> | 123K|
  1510. X                1,234,567 -> |   1M|
  1511. X               12,345,678 -> |  12M|
  1512. X             12,345,678.1 -> |  12M|
  1513. X   12,345,678.1199 9999 9 -> |  12M|
  1514. X           12,345,678.123 -> |  12M|
  1515. X   12,345,678.1233 9999 9 -> |  12M|
  1516. X        12,345,678.1234 5 -> |  12M|
  1517. X                       -1 -> |   -1|
  1518. X                      -12 -> |  -12|
  1519. X                     -123 -> | -123|
  1520. X                   -1,234 -> |  -1K|
  1521. X                  -12,345 -> | -12K|
  1522. X                 -123,456 -> |-123K|
  1523. X               -1,234,567 -> |  -1M|
  1524. X              -12,345,678 -> | -12M|
  1525. X            -12,345,678.1 -> | -12M|
  1526. X  -12,345,678.1199 9999 9 -> | -12M|
  1527. X          -12,345,678.123 -> | -12M|
  1528. X  -12,345,678.1233 9999 9 -> | -12M|
  1529. X       -12,345,678.1234 5 -> | -12M|
  1530. X                      9.1 -> |  9.1|
  1531. X                     9.12 -> | 9.12|
  1532. X                    9.123 -> |9.123|
  1533. X                   9.1234 -> |9.123|
  1534. X                 9.1234 5 -> |9.123|
  1535. X                      0.1 -> |  0.1|
  1536. X                     0.02 -> | 0.02|
  1537. X                    0.003 -> |0.003|
  1538. X                   0.0004 -> | 0.4m|
  1539. X                 0.0000 5 -> |0.05m|
  1540. XWidth set to 5 and don't use seps.
  1541. X                    Input    |-----|
  1542. X                        1 -> |    1|
  1543. X                       12 -> |   12|
  1544. X                      123 -> |  123|
  1545. X                    1,234 -> | 1234|
  1546. X                   12,345 -> |12345|
  1547. X                  123,456 -> | 123K|
  1548. X                1,234,567 -> |1235K|
  1549. X               12,345,678 -> |  12M|
  1550. X             12,345,678.1 -> |  12M|
  1551. X   12,345,678.1199 9999 9 -> |  12M|
  1552. X           12,345,678.123 -> |  12M|
  1553. X   12,345,678.1233 9999 9 -> |  12M|
  1554. X        12,345,678.1234 5 -> |  12M|
  1555. X                       -1 -> |   -1|
  1556. X                      -12 -> |  -12|
  1557. X                     -123 -> | -123|
  1558. X                   -1,234 -> |-1234|
  1559. X                  -12,345 -> | -12K|
  1560. X                 -123,456 -> |-123K|
  1561. X               -1,234,567 -> |  -1M|
  1562. X              -12,345,678 -> | -12M|
  1563. X            -12,345,678.1 -> | -12M|
  1564. X  -12,345,678.1199 9999 9 -> | -12M|
  1565. X          -12,345,678.123 -> | -12M|
  1566. X  -12,345,678.1233 9999 9 -> | -12M|
  1567. X       -12,345,678.1234 5 -> | -12M|
  1568. X                      9.1 -> |  9.1|
  1569. X                     9.12 -> | 9.12|
  1570. X                    9.123 -> |9.123|
  1571. X                   9.1234 -> |9.123|
  1572. X                 9.1234 5 -> |9.123|
  1573. X                      0.1 -> |  0.1|
  1574. X                     0.02 -> | 0.02|
  1575. X                    0.003 -> |0.003|
  1576. X                   0.0004 -> | 0.4m|
  1577. X                 0.0000 5 -> |0.05m|
  1578. XWidth set to 15
  1579. X                    Input    |---------------|
  1580. X                        1 -> |              1|
  1581. X                       12 -> |             12|
  1582. X                      123 -> |            123|
  1583. X                    1,234 -> |          1,234|
  1584. X                   12,345 -> |         12,345|
  1585. X                  123,456 -> |        123,456|
  1586. X                1,234,567 -> |      1,234,567|
  1587. X               12,345,678 -> |     12,345,678|
  1588. X             12,345,678.1 -> |   12,345,678.1|
  1589. X   12,345,678.1199 9999 9 -> |  12,345,678.12|
  1590. X           12,345,678.123 -> | 12,345,678.123|
  1591. X   12,345,678.1233 9999 9 -> |12,345,678.1234|
  1592. X        12,345,678.1234 5 -> |12,345,678.1234|
  1593. X                       -1 -> |             -1|
  1594. X                      -12 -> |            -12|
  1595. X                     -123 -> |           -123|
  1596. X                   -1,234 -> |         -1,234|
  1597. X                  -12,345 -> |        -12,345|
  1598. X                 -123,456 -> |       -123,456|
  1599. X               -1,234,567 -> |     -1,234,567|
  1600. X              -12,345,678 -> |    -12,345,678|
  1601. X            -12,345,678.1 -> |  -12,345,678.1|
  1602. X  -12,345,678.1199 9999 9 -> | -12,345,678.12|
  1603. X          -12,345,678.123 -> |-12,345,678.123|
  1604. X  -12,345,678.1233 9999 9 -> |-12,345,678.123|
  1605. X       -12,345,678.1234 5 -> |-12,345,678.123|
  1606. X                      9.1 -> |            9.1|
  1607. X                     9.12 -> |           9.12|
  1608. X                    9.123 -> |          9.123|
  1609. X                   9.1234 -> |         9.1234|
  1610. X                 9.1234 5 -> |       9.1234 5|
  1611. X                      0.1 -> |            0.1|
  1612. X                     0.02 -> |           0.02|
  1613. X                    0.003 -> |          0.003|
  1614. X                   0.0004 -> |         0.0004|
  1615. X                 0.0000 5 -> |       0.0000 5|
  1616. END_OF_FILE
  1617. if test 12068 -ne `wc -c <'my.out'`; then
  1618.     echo shar: \"'my.out'\" unpacked with wrong size!
  1619. fi
  1620. # end of 'my.out'
  1621. fi
  1622. if test -f 'test.C' -a "${1}" != "-c" ; then 
  1623.   echo shar: Will not clobber existing file \"'test.C'\"
  1624. else
  1625. echo shar: Extracting \"'test.C'\" \(2719 characters\)
  1626. sed "s/^X//" >'test.C' <<'END_OF_FILE'
  1627. X#include "fformat.h"
  1628. X#include <math.h>
  1629. X
  1630. X// Function prototypes
  1631. X
  1632. Xconst SAMPLEWIDTH = 25;
  1633. X
  1634. Xvoid test_switches();
  1635. Xvoid show_width(int width);
  1636. Xint main()
  1637. X{
  1638. X    test_switches();
  1639. X    
  1640. X    return 0;
  1641. X}
  1642. X
  1643. Xvoid test_switches()
  1644. X{
  1645. X    const width2 = 7;
  1646. X    const width3 = 7;
  1647. X    const sepw4 = 4;
  1648. X    const width5 = 5;
  1649. X    const width6 = 5;
  1650. X    const width7 = 15;
  1651. X
  1652. X    const max_sig = 7;
  1653. X    ld l;
  1654. X    FFormat sample;
  1655. X    sample.SetWidth(SAMPLEWIDTH);
  1656. X
  1657. X    for (int j = 0; j <= 7; j++) {
  1658. X        FFormat a;
  1659. X
  1660. X//        a.SetUseExp(1);
  1661. X        switch (j) {
  1662. X        case 0:
  1663. X            cout << "Default." << endl;
  1664. X            break;
  1665. X        case 1:
  1666. X            cout << "Don't use the separators." << endl;
  1667. X            a.SetUseSeparators(0);
  1668. X            break;
  1669. X        case 2:
  1670. X            cout << "Set width to " << width2 <<
  1671. X                " and don't right adjust." << endl;
  1672. X            a.SetWidth(width2);
  1673. X            a.SetRightAdjust(0);
  1674. X            break;
  1675. X        case 3:
  1676. X            cout << "Set width to " << width3 <<
  1677. X                " and don't use SI." << endl;
  1678. X            a.SetWidth(width3);
  1679. X            a.SetUseSI(0);
  1680. X            break;
  1681. X        case 4:
  1682. X            cout << "Set separator width to " << sepw4 <<
  1683. X                " and Sep is a space." << endl;
  1684. X
  1685. X            a.SetSep(' ');
  1686. X            a.SetSepWidth(sepw4);
  1687. X            break;
  1688. X        case 5:
  1689. X            cout << "Normal SepWidth, but Width set to " << width5 << endl;
  1690. X            a.SetWidth(width5);
  1691. X            break;
  1692. X        case 6:
  1693. X            cout << "Width set to " << width6 << " and don't use seps." << endl;
  1694. X            a.SetWidth(width6);
  1695. X            a.SetUseSeparators(0);
  1696. X            break;
  1697. X        case 7:
  1698. X            cout << "Width set to " << width7 << endl;
  1699. X            a.SetWidth(width7);
  1700. X            break;
  1701. X        }
  1702. X        l = 1;
  1703. X        show_width(a.Width());
  1704. X        for (int i = 0; i < max_sig; i++) {
  1705. X            cout << sample.Str(l) << flush;
  1706. X            cout << " -> |";
  1707. X            cout << a.Str(l);
  1708. X            cout << "|" << endl;
  1709. X            l *= 10;
  1710. X            l += (i + 2) % 10;
  1711. X        }
  1712. X        for (i = 1; i < max_sig; i++) {
  1713. X            cout << sample.Str(l) << flush;
  1714. X            cout << " -> |";
  1715. X            cout << a.Str(l);
  1716. X            cout << '|' << endl;
  1717. X            l += i / pow(10, i);
  1718. X        }
  1719. X        l = -1;
  1720. X        for (i = 0; i < max_sig; i++) {
  1721. X            cout << sample.Str(l) << flush;
  1722. X            cout << " -> |";
  1723. X            cout << a.Str(l);
  1724. X            cout << "|" << endl;
  1725. X            l *= 10;
  1726. X            l -= (i + 2) % 10;
  1727. X        }
  1728. X        for (i = 1; i < max_sig; i++) {
  1729. X            cout << sample.Str(l) << flush;
  1730. X            cout << " -> |";
  1731. X            cout << a.Str(l);
  1732. X            cout << '|' << endl;
  1733. X            l -= i / pow(10, i);
  1734. X        }
  1735. X        l = 9.1;
  1736. X        for (i = 2; i < max_sig; i++) {
  1737. X            cout << sample.Str(l) << flush;
  1738. X            cout << " -> |";
  1739. X            cout << a.Str(l);
  1740. X            cout << '|' << endl;
  1741. X            l += i / pow(10, i);
  1742. X        }
  1743. X        l = .1;
  1744. X        for (i = 2; i < max_sig; i++) {
  1745. X            cout << sample.Str(l) << flush;
  1746. X            cout << " -> |";
  1747. X            cout << a.Str(l);
  1748. X            cout << '|' << endl;
  1749. X            l = i / pow(10, i);
  1750. X        }
  1751. X
  1752. X    }
  1753. X}
  1754. X
  1755. Xvoid show_width(int width)
  1756. X{
  1757. X    int i;
  1758. X
  1759. X    for (i = 0; i < SAMPLEWIDTH - 5; i++) 
  1760. X        cout << ' ';
  1761. X    cout << "Input";
  1762. X    cout << "    |";
  1763. X    if (width) {
  1764. X        for (i = 0; i < width; i++)
  1765. X            cout << '-';
  1766. X    }
  1767. X    else {
  1768. X        cout << "Unlimited";
  1769. X    }
  1770. X    cout << '|' << endl;;
  1771. X}
  1772. END_OF_FILE
  1773. if test 2719 -ne `wc -c <'test.C'`; then
  1774.     echo shar: \"'test.C'\" unpacked with wrong size!
  1775. fi
  1776. # end of 'test.C'
  1777. fi
  1778. if test -f 'test.bat' -a "${1}" != "-c" ; then 
  1779.   echo shar: Will not clobber existing file \"'test.bat'\"
  1780. else
  1781. echo shar: Extracting \"'test.bat'\" \(208 characters\)
  1782. sed "s/^X//" >'test.bat' <<'END_OF_FILE'
  1783. X@echo on
  1784. Xrem set prog=go32 test
  1785. Xset prog=fformat
  1786. Xecho Renaming all *.c to *.cc
  1787. Xren *.c *.cc
  1788. Xecho Test routine for IFormat - should read "FC: no differences encountered"
  1789. X%prog% > your.out
  1790. Xfc my.out your.out
  1791. X
  1792. X
  1793. END_OF_FILE
  1794. if test 208 -ne `wc -c <'test.bat'`; then
  1795.     echo shar: \"'test.bat'\" unpacked with wrong size!
  1796. fi
  1797. # end of 'test.bat'
  1798. fi
  1799. if test -f 'test.sh' -a "${1}" != "-c" ; then 
  1800.   echo shar: Will not clobber existing file \"'test.sh'\"
  1801. else
  1802. echo shar: Extracting \"'test.sh'\" \(403 characters\)
  1803. sed "s/^X//" >'test.sh' <<'END_OF_FILE'
  1804. X#!/bin/sh
  1805. X## Test routine for IFormat
  1806. X
  1807. Xmake test
  1808. Xfformat > your.out
  1809. Xlines=`diff my.out your.out | wc -l`
  1810. Xif (test $lines -ne 0) then
  1811. X    echo "Your output is different then my output, but then"
  1812. X    echo "different machines round differntly (probably not serious)."
  1813. X    echo "Here's what diff gave me"
  1814. X    echo "diff my.out your.out"
  1815. X    diff my.out your.out
  1816. Xelse
  1817. X    fformat | more
  1818. X    echo 'Passed test'
  1819. X    rm -f your.out
  1820. Xfi
  1821. END_OF_FILE
  1822. if test 403 -ne `wc -c <'test.sh'`; then
  1823.     echo shar: \"'test.sh'\" unpacked with wrong size!
  1824. fi
  1825. chmod +x 'test.sh'
  1826. # end of 'test.sh'
  1827. fi
  1828. echo shar: End of archive 1 \(of 1\).
  1829. cp /dev/null ark1isdone
  1830. MISSING=""
  1831. for I in 1 ; do
  1832.     if test ! -f ark${I}isdone ; then
  1833.     MISSING="${MISSING} ${I}"
  1834.     fi
  1835. done
  1836. if test "${MISSING}" = "" ; then
  1837.     echo You have the archive.
  1838.     rm -f ark[1-9]isdone
  1839. else
  1840.     echo You still need to unpack the following archives:
  1841.     echo "        " ${MISSING}
  1842. fi
  1843. ##  End of shell archive.
  1844. exit 0
  1845.  
  1846.  
  1847. -- 
  1848. -------------------- kirkwood@qucis.queensu.ca ----------------------
  1849.       299,792,458 m/s it's not just a good idea, it's the law!
  1850.  
  1851.  
  1852. exit 0 # Just in case...
  1853.