home *** CD-ROM | disk | FTP | other *** search
/ NetNews Usenet Archive 1992 #30 / NN_1992_30.iso / spool / comp / sources / misc / 4163 < prev    next >
Encoding:
Text File  |  1992-12-12  |  53.0 KB  |  1,859 lines

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