home *** CD-ROM | disk | FTP | other *** search
- /****************************************************************************
-
- FREE : free.c checks disk free space, with options
-
- Author : Howard S. Kapustein
-
- Program, Source, Documentation Copyright (c) 1988,1989 all rights reserved.
-
- Compiled code may be used in your library, and linked to your programs
- BUT, the source code nor a library based on the compiled modules may be
- commercially distributed.
- I retain all rights to the source (this is all lawyer talk. I just don't
- want someone making money off my efforts.)
- No donation is expected. If you like FREE, send me a picture postcard
- or, if you must, $5. I am a poor starving college student and will
- gladly accept all comments, questions, suggestions and/or donations.
-
- For a quick start try FREE -?
-
- I know this is a pretty simple program. There are plenty of versions
- of free disk space programs in the public domain, but none suited my
- needs. I needed 3 features besides the standard disk space free:
-
- 1) Check more than 1 drive per run
- 2) Optionally check all drives
- 3) Optionally wait for a keypress after execution for use
- with DESQview (tm)
-
- FREE.C, FREE.EXE and FREE.DOC must be distributed together.
-
- FREE was compiled with Turbo C (tm) 2.0 on an IBM PC with the Tiny
- memory model optimized on Speed and all optimizations turned on
- (Register and Jump optimization).
-
- Release notes: 2-2-88 Version 1.0 - Initial release
-
- 2-22-88 Version 1.1
- - checks for drive ready before checking
- free space
- - skips drive B: only 1 drive present
- (B: is a logical drive, not a physical
- drive)
- - optional wait after execution can now
- wait for a specific key (specify its
- decimal scan code, only valid for keys
- 1-255 (no extended keys i.e. Alt-C, etc.)
- - fixed a bug with the strtocomma() function.
- If a 4-digit number (i.e. 9216) was passed
- to it it would not insert any commas
- - I no longer make FREE.COM, for some reason
- under DESQview FREE.COM 1.0 still needed
- approx 70K, so until I can figure out how
- to get FREE to use appropriate only the 11K
- or so it needs, I'm not going to bother
- playing with COM files
-
- 2-29-88 Version 1.2
- - recompiled under Turbo C 1.5 (it only took
- them 6 weeks instead of the 2-3 it should
- have...) I turned on ALL optimizations
- (speed, use regs, optimize regs and jumps.)
- Previous versions were only compiled with
- speed and use registers.
- - modified the parsing for more coherent
- program flow
- - made waitforkey() after having extensive
- difficulties getting the -w option to work.
- This seems to have fixed the runtime bugs
- I was getting after recompiling with TC 1.5
- - changed the HEAP and STACK size so it will
- run with less memory
- - removed some needless comments left over
- from old coding
- - include a DESQview .DVP file for use with
- DESQview.
-
- 3-19-88 Version 1.3
- - fixed the bug with multiple drives
- specified on the command line. It seems
- that TC 1.5 DOES NOT let you use the
- generic argc and argv as in
- main(int argc, char *argv[]) Now Borland
- wants you to use their global variables
- (extern int argc, etc.). Nice of them not
- to mention the fact that the old method
- no longer works.
-
- 3-23-88 Version 1.31 - Internal release only
- - if you try to do a FREE - with no
- parms free would check the default drive.
- This has been fixed to display the help
- (technically, doing FREE - is wrong)
- - version 1.2 allowed -w[n] option to check
- for extended key codes, but I forgot to
- document it. Use this formula to get the
- value for the wait option:
-
- extended * 256 + scancode
-
- where extended is 0 if False and 1 if True
- and scancode is the scan code returned by
- the key (refer to one of Norton's books
- or some other reference guide for a list
- of IBM extended scan codes.)
-
- 4-10-88 Version 1.32 - Internal release only
- - I removed a printf() left over from
- debugging
- - included info about contacting me during
- the school year
-
- 5-6-88 Version 1.33 - Internal release only
- - included % free
-
- 5-11-88 Version 1.34 - Internal release only
- - fixed -w option, was skipping past
- 1st digit of keycode ([n])
- - also, discovered the problem with the
- -w option. Compiled w/full optimization,
- the waitkey value was stored in a
- register which was destroyed during the
- absread(). This is a problem of the
- TC library itself. I don't remember
- who it was who discovered this flaw, but
- if you drop me a line I'll update these
- docs. He has notified Borland, so
- hopefully the next TC will have this bug
- fixed (if not sooner, but I'm not
- holding my breath.) Thank you for the
- debugging, it gave me many a restless
- hour. DO NOT compile FREE with register
- variables on, or unknown results may
- (and probably will) occur
-
- 11-9-88 Version 1.4
- - recompiled under TC 2.0 in Small model,
- Merge duplicate strings On, Standard
- stack frame Off, and all Debug info
- left out. Couldn't compile under Tiny
- (Cannot generate COM file: segment-
- relocatable items present) probably because
- of the FP emulator - see below
- - added optional message if wait for key
- - added -f and -n (search only floppies,
- non-floppies). The -x option is equivalent
- to -fn
- - added -e option (full error display, useful
- if you want to see any errors during a -f,
- -n, or -x run). This setting is turned on
- automatically for single mode (if -f, -n
- and -x are not specified)
- - minor code tinkering for aesthetics
- - DESQview 2.2 .DVP file
- - for some reason, FREE running under
- DV 2.2 now requires 65K. According to my
- estimates, it needs anywhere from 44K to
- 66K. I think this is related to the Tiny
- problem (inability to make .COM file). If
- anyone can figure out why, please let me
- know. Without the FP emulator, I can't
- display a % free, but requiring 65K to get
- a free disk space count is ridiculous
-
- 2-7-89 Version 1.5
- - new option -N, Network compatibility,
- skips the absolute disk read before
- checking free space. If a free space
- request is attempted on drive A: with
- no floppy in the drive, DOS bombs out to
- the Abort,Ignore,Retry message. Turning on
- this option should allow execution on
- drives not physically available (networks,
- those accessed via device drivers, etc.)
- - changed option letter -N to -H to allow
- network compatibility. The -H option
- will scan non-floppy drives (generally
- fixed disks, C: and up.)
- - no longer compiled with the FP emulation,
- the % free real number is now achieved via
- integers. Without the FP emulation FREE can
- be compiled with the Tiny memory model.
- - added check for DOS environment variable
- FREEOPT for options
- - changed the Heap size to 4K and the stack
- to 1K
- - changed the command line parsing to a
- separate function, and no longer copy each
- *_argv before processing it. The pointer
- char *temp replace the older char temp[30]
- for several reasons: instead of a strcpy()
- we can just do a temp = *_argv, and if an
- argument string was longer than 29
- characters, we would have problems copying
- to temp[30]. Pointers make life simpler
- - you can now check multiple drives via
- command line switch, and specific drives
- via drive letter, in the same run (i.e.
- FREE /F B: checks all floppy drives and
- drive B:)
- - IMPORTANT! FREE is now distributed as a
- .COM file! If you are using an earlier
- verison with a .EXE extension, make sure
- you delete it otherwise DOS may not find
- the proper file to run. See above regarding
- FP emulation as to why we're back to a
- .COM file.
- Note: I've enclosed the substitute division
- function within a conditional #if...#endif
- set so you can recompile easily with the
- emulation or 8087 library and not have
- unnecessary code. If MATH_FP87 or MATH_EMU
- is #defined, the rdiv() function will not
- be compiled. Otherwise, no math library
- will be linked in, and the final .COM
- will only need ~15K to run.
-
- 2-8-89 Version 1.51
- - if no command line arguments given, only
- the current drive would be checked, even
- if FREEOPT=X. Fixed
-
- 2-17-89 Version 1.6
- - new option -t gives disk total size, used
- disk space, etc. a list of all disk space
- info. To do this, the functions rsub_t(),
- rnormalize() and lpow() were created (real
- subtraction w/o a math library), as well
- as their attendant global variables.
- WARNING: these substitute floating point math
- functions have minimal error checking.
- Given the scope of this program, they
- are adequate, but for a more complete
- implementation of these (and other)
- functions, try my Turbo C library TCHK
- (currently distributed as TCHK20.ARC).
- NOTE: as per the rdiv() function, these
- substitute fp functions/variables are
- enclosed within #if...#endif to avoid
- compilation if a fp library is used.
- FURTHER: the compiler may generate 2 warnings
- (structure passed by value) if your
- warning settings are just right. Don't
- worry about it, those are the structures
- passed to rsub(). It's valid C (or at
- least ANSI C) but potentially erroneous
- to pass structures instead of pointers to
- structures, so Turbo C warns you.
- - changed the code to check only as many
- drives as DOS recognizes. Under DOS 1.x,
- 2.x and 3.x, there can be as many as 16,
- 63 or 26 drives available, respectively.
- Previously I just checked drives 1-26
- (A:-Z:), which was an erroneous assumption
- on my part. Thanks to John Craven for
- mentioning Int 21h Function 0Eh (setdisk()
- in Turbo C) as the proper method for
- detecting the number of logical drives.
- - changed the code to skip B: if it does
- not physically exist. This should clear
- up the problem Michael Thompson has been
- having with the scan drives (/x or /f)
- option.
-
-
- I can be reached at:
-
- Home: Howard S. Kapustein
- 1695 Barbara Lane
- East Meadow, New York 11554
- Phone: (516) 481-9612
-
- College (until 5-19-89): Howard S. Kapustein
- 404 Davison
- Rensselaer Polytechnic Institute
- Troy, NY 12180
- (518) 276-7381
-
- Modem: The BOSS (201) 568-7293 ***Support BBS
- Software Society (201) 729-7410
- Computer Connection (202) 547-2008
- GEnie
-
- Until graduation (May 19, 1989) please try to contact me
- at college. If you call my home while I'm in Troy you're not
- likely to get much information (my parents aren't exactly
- computer people.)
-
-
- ****************************************************************************/
-
- #include <ctype.h>
- #include <bios.h>
- #include <dos.h>
- #include <string.h>
- #include <stdlib.h>
- #include <stdio.h>
- #include <dir.h>
- typedef struct rdiv_t {
- long rint; /* real - integer */
- long rfrac; /* real - fraction */
- int precision; /* precision of fraction (# of decimal places) */
- };
-
- #define TRUE 1
- #define FALSE 0
- #define boolean char
- #define BUFF_LEN 512 /* buffer length for disk read */
- #define FLOPPY 0x10
- #define FIXED 0x20
- #define ALLDRIVES (FIXED|FLOPPY)
- #define isBlogical() ((biosequip()&0xB0)?FALSE:TRUE)
- #define MAXRPRECISION 8 /* maximum real precision (decimal places) */
- #define _HEADING_ "FREE Free disk space Version 1.6 2-17-89 FREE/?\n"
- #define _HEADINGCOPY_ "Copyright (c) 1988,1989 Howard Kapustein. All Rights Reserved for help\n\n"
-
- typedef struct options {
- char scandrives;
- boolean network;
- boolean disktotal;
- boolean checkmemory;
- boolean errormsg;
- boolean wait;
- boolean waitmsg;
- int waitkey;
- };
-
- /* Global variables */
- struct options flag;
- #if !defined(MATH_FP87) && !defined(MATH_EMU) /* using no math library */
- int _r_minpre, _r_maxpre;
- boolean _r_maximum = FALSE; /* should rnormalize() try to minimize or maximize the precision */
- #endif
-
- /* function prototypes */
- void main(); /* prevents compiler warning */
- void check(int drive); /* actual free space check and output */
- char *strtocomma(char *source); /* convert a string to xx,xxx,xxx format */
- void help(void); /* help */
- void waitforkey(int keycode, boolean msg); /* wait for keypress when done */
- void parsecommandline(char *cmdline); /* parse a command line */
- void bye(int errcode); /* generalized quit routine */
- struct rdiv_t rdiv(long int numer, long int denom, int precision); /* real division without FP emulator library */
- struct rdiv_t rsub(struct rdiv_t val, struct rdiv_t sval, int precision); /* real subtraction without FP emulator library */
- void rnormalize(struct rdiv_t *r1, struct rdiv_t *r2); /* normalize emulated fp values (fix the decimal places) */
- long lpow(long base, int exponent); /* raise a base to an exponent */
-
-
- void main()
- {
- extern int _argc;
- extern char **_argv;
- extern unsigned _heaplen, _stklen;
- char *temp;
- boolean Blogical;
- int i, floppies, totaldrives;
-
- _heaplen = 4096u; /* heap = 4K */
- _stklen = 1024u; /* stack = 1K */
-
- _argc--;
- _argv++;
-
- flag.scandrives = FALSE; /* initialize settings */
- flag.network = FALSE;
- flag.disktotal = FALSE;
- flag.checkmemory = FALSE;
- flag.errormsg = FALSE;
- flag.wait = FALSE;
- flag.waitmsg = TRUE;
- flag.waitkey = 0;
-
- if ((temp = getenv("FREEOPT")) != NULL)
- parsecommandline(temp);
-
- if (_argc > 0) /* check for options */
- for (temp = *_argv; (temp[0] == '-') || (temp[0] == '/'); temp = *_argv) {
- if (temp[1] == '\0')
- help();
- parsecommandline(temp+1);
- _argc--;
- _argv++;
- if (_argc == 0)
- break;
- }
-
- if (flag.disktotal)
- fputs("\n" _HEADING_ _HEADINGCOPY_
- "Drive Size Used Free % Used % Free\n"
- "----- ---------- ---------- ---------- ------ ------\n",stdout);
-
- if (flag.scandrives) { /* check multiple drives? */
- floppies = ((biosequip() & 0xB0) >> 6) + 1;
- Blogical = (floppies > 1) ? FALSE : TRUE;
- if (flag.scandrives & FLOPPY) /* check floppy drives? */
- for (i=1; i<=floppies; i++) /* check floppies */
- if (!(Blogical && i==2))
- check(i);
- if (flag.scandrives & FIXED) { /* check non-floppies? */
- totaldrives = setdisk(getdisk());
- i = ++floppies;
- if (Blogical)
- i++;
- for (; i<=totaldrives; i++) /* check hard drives */
- check(i);
- }
- }
-
- if ((_argc == 0) && !flag.scandrives) { /* ok, just parms (no drive specified) */
- flag.errormsg = TRUE; /* force error message display for non-multiple mode */
- check(0);
- if (flag.wait)
- waitforkey(flag.waitkey,flag.waitmsg);
- bye(3);
- }
-
- flag.errormsg = TRUE; /* force error message display for non-multiple mode */
- for (; _argc>0; _argc--, _argv++) {
- strcpy(temp,*_argv);
- if (!isalpha(temp[0]=toupper(temp[0])))
- printf("Invalid drive: %c\n",temp[0]);
- else
- check(temp[0]-64);
- }
-
- if (flag.wait)
- waitforkey(flag.waitkey,flag.waitmsg);
- }
-
-
- void check(int drive)
- {
- extern struct options flag;
- struct dfree df;
- char size[30];
- unsigned char buffer[BUFF_LEN];
- long avail, total;
- #if defined(MATH_FP87) || defined(MATH_EMU) /* using 80x87 or Emulation math library */
- double percent;
- #else /* using No math library */
- struct rdiv_t percent, percentused, percent100;
- percent100.rint = 100l;
- percent100.rfrac = 0l;
- percent100.precision = MAXRPRECISION;
- #endif
-
- if (drive==0)
- drive = getdisk() + 1;
- if (!flag.network && absread(drive-1,1,0,buffer)==-1) { /* error */
- if (flag.errormsg)
- printf("Drive %c: is not available (drive not ready)\n",drive+64);
- } else {
- getdfree(drive,&df);
- if (df.df_sclus == (unsigned)(-1)) { /* error */
- if (flag.errormsg)
- printf("Drive %c: is not available (can't get free space)\n",drive+64);
- } else {
- avail = (long)df.df_avail * df.df_bsec * df.df_sclus;
- total = (long)df.df_total * df.df_bsec * df.df_sclus;
- #if defined(MATH_FP87) || defined(MATH_EMU) /* using 80x87 or Emulation math library */
- percent = (avail * 100.0) / ((long)df.df_total * df.df_bsec * df.df_sclus);
- if (flag.disktotal)
- printf(" %c: %10ld %10ld %10ld %6.2lf %6.2lf\n",drive+64,total,total-avail,avail,100.0-percent,percent);
- else {
- ltoa(avail,size,10);
- printf("Drive %c: has %s bytes free (%.2lf %%)\n",drive+64,strtocomma(size),percent);
- }
- #else /* using No math library */
- percent = rdiv(avail,total,4);
- percent.rint = percent.rint * 100l + percent.rfrac / 100l;
- percent.rfrac %= 100l;
- percent.precision -= 2;
- percentused = rsub(percent100,percent,2);
- if (flag.disktotal)
- printf(" %c: %10ld %10ld %10ld %3ld.%02ld %3ld.%02ld\n",drive+64,total,total-avail,avail,
- percentused.rint,percentused.rfrac,percent.rint,percent.rfrac);
- else {
- ltoa(avail,size,10);
- printf("Drive %c: has %s bytes free (%ld.%02ld %%)\n",drive+64,strtocomma(size),percent.rint,percent.rfrac);
- }
- #endif
- }
- }
- }
-
-
- char *strtocomma(char *source) /* convert a string to xx,xxx,xxx format */
- {
- char temp[80],*t,*s;
- int i,len;
-
- len = strlen(source) * 4/3 + 1;
- strcpy(temp,"");
- if ((len = strlen(source)) <= 3)
- strcpy(temp,source);
- else
- for (i=len, t=temp, s=source; i>0; i--) {
- if ((i%3 == 0) && (i != len))
- *t++ = ',';
- *t++ = *s++;
- }
- *t = '\0';
- strcpy(source,temp);
- return(source);
- }
-
-
- void help(void)
- {
- fputs(_HEADING_ _HEADINGCOPY_,stdout);
- fputs("Usage: FREE [options] [drive] [drive] [drive] ...\n",stdout);
- fputs("Options are:\n",stdout);
- fputs(" -e = display all error messages -f = check all floppy drives\n",stdout);
- fputs(" -n = network compatibility -h = check all non-floppy drives\n",stdout);
- fputs(" -t = display total disk size -x = check all drives\n",stdout);
- fputs(" -w[0][n] = wait for keypress when done -? = help\n\n",stdout);
- fputs("If you like FREE send me a picture postcard or $5. I can be reached at:\n\n",stdout);
- fputs("VOICE: Howard Kapustein MODEM: The BOSS (201) 568-7293 **Support BBS\n",stdout);
- fputs(" 1695 Barbara Lane Software Society (201) 729-7410\n",stdout);
- fputs(" East Meadow, New York 11554 Computer Connection (202) 547-2008\n",stdout);
- fputs(" Phone: (516) 481-9612 GEnie: Howard S. Kapustein\n\n",stdout);
- fputs("I am a poor starving college senior, 404 Davison\n",stdout);
- fputs("so all donations (and job offers) Rensselaer Polytechnic Institute\n",stdout);
- fputs("will be appreciated. Until graduation Troy, NY 12180\n",stdout);
- fputs("(May 19, 1989) PLEASE contact me at -> Phone: (518) 276-7381\n\n",stdout);
- fputs("I also write Subtree Find (SF310.ARC), TCHK (TCHK20.ARC) and other shareware.\n",stdout);
- bye(9);
- }
-
-
- void waitforkey(int keycode, boolean msg) /* wait for keypress when done */
- {
- int key;
-
- if (msg) {
- if (keycode == 0)
- fputs("Press any key to end...",stdout);
- else
- printf("Press key #%d to end...",keycode);
- }
- if (keycode == 0)
- bioskey(0);
- else
- do {
- key = bioskey(0);
- if (key & 0xFF)
- key = key & 0xFF;
- else
- key = ((key & 0xFF00) >> 8) + 256;
- } while (key != keycode);
- }
-
-
- void parsecommandline(char *cmdline)
- {
- extern struct options flag;
- int i;
-
- for (i=0; cmdline[i]!='\0'; i++)
- switch (toupper(cmdline[i])) {
- case '/': { if (cmdline[++i] == '\0')
- bye(67);
- break; }
- case 'N': { switch (cmdline[i+1]) {
- case '-': { flag.network = FALSE;
- i++;
- break; }
- case '*': { flag.network ^= TRUE;
- i++;
- break; }
- case '+': i++;
- default: flag.network = TRUE; break;
- }
- break; }
- case 'E': { switch (cmdline[i+1]) {
- case '-': { flag.errormsg = FALSE;
- i++;
- break; }
- case '*': { flag.errormsg ^= TRUE;
- i++;
- break; }
- case '+': i++;
- default: flag.errormsg = TRUE; break;
- }
- break; }
- case 'F': { switch (cmdline[i+1]) {
- case '-': { flag.scandrives &= ~FLOPPY;
- i++;
- break; }
- case '*': { flag.scandrives ^= FLOPPY;
- i++;
- break; }
- case '+': i++;
- default: flag.scandrives |= FLOPPY; break;
- }
- break; }
- case 'H': { switch (cmdline[i+1]) {
- case '-': { flag.scandrives &= ~FIXED;
- i++;
- break; }
- case '*': { flag.scandrives ^= FIXED;
- i++;
- break; }
- case '+': i++;
- default: flag.scandrives |= FIXED; break;
- }
- break; }
- case 'M': { switch (cmdline[i+1]) {
- case '-': { flag.checkmemory = FALSE;
- i++;
- break; }
- case '*': { flag.checkmemory ^= TRUE;
- i++;
- break; }
- case '+': i++;
- default: flag.checkmemory = TRUE; break;
- }
- break; }
- case 'T': { switch (cmdline[i+1]) {
- case '-': { flag.disktotal = FALSE;
- i++;
- break; }
- case '*': { flag.disktotal ^= TRUE;
- i++;
- break; }
- case '+': i++;
- default: flag.disktotal = TRUE; break;
- }
- break; }
- case 'X': { switch (cmdline[i+1]) {
- case '-': { flag.scandrives &= ~ALLDRIVES;
- i++;
- break; }
- case '*': { flag.scandrives ^= ALLDRIVES;
- i++;
- break; }
- case '+': i++;
- default: flag.scandrives |= ALLDRIVES; break;
- }
- break; }
- case 'W': { if (isdigit(cmdline[i+1])) {
- flag.waitmsg = (cmdline[++i] == '0') ? FALSE : TRUE;
- flag.waitkey = atoi(cmdline+i);
- for (; isdigit(cmdline[i+1]); i++);
- } else
- flag.waitkey = 0;
- switch (cmdline[i+1]) {
- case '-': { flag.wait = FALSE;
- i++;
- break; }
- case '*': { flag.wait ^= TRUE;
- i++;
- break; }
- case '+': i++;
- default: flag.wait = TRUE; break;
- }
- break; }
- case '?': help();
- default : { printf("Unknown parameter: %c\n",cmdline[i]); bye(11); }
- }
- }
-
-
- void bye(int errcode) /* generalized quit routine */
- {
- exit(errcode);
-
- /* A separate quit function is not really necessary at this time,
- but it allows for potential error checking and cleanup just before
- exiting. Perhaps a future version will have more here. Included for
- upward compatibility purposes. */
- }
-
-
- #if !defined(MATH_FP87) && !defined(MATH_EMU) /* using no math library */
- struct rdiv_t rdiv(long int numer, long int denom, int precision) /* real division without FP emulator library */
- {
- struct rdiv_t retval;
- long i;
-
- if (denom == 0l) {
- retval.rint = -1;
- retval.rfrac = -1;
- return(retval);
- }
- retval.precision = precision; /* store precision of fraction */
- retval.rint = numer / denom;
- denom -= numer * retval.rint;
- retval.rfrac = 0l;
- if (denom == 0l)
- return(retval);
- for (; precision >= 0; precision--) {
- numer *= 10l;
- i = numer / denom;
- if (precision != 0)
- retval.rfrac = retval.rfrac * 10l + i;
- else
- if (numer / denom >= 5l) /* round off last decimal place */
- retval.rfrac++;
- numer = numer - i * denom;
- }
- return(retval);
- }
-
-
- struct rdiv_t rsub(struct rdiv_t val, struct rdiv_t sval, int precision) /* real subtraction without FP emulator library */
- {
- extern int _r_minpre;
- struct rdiv_t retval;
- int i;
-
- rnormalize(&val,&sval);
- retval.rint = val.rint - sval.rint;
- if (val.rfrac < sval.rfrac) {
- retval.rint--; /* carry the one... */
- val.rfrac += lpow(10l,val.precision);
- }
- retval.rfrac = val.rfrac - sval.rfrac;
- retval.precision = precision;
- i = precision - _r_minpre;
- if (i < 0)
- for (; i<0; i++)
- retval.rfrac /= 10l;
- else if (i > 0)
- for (; i>0; i--)
- retval.rfrac *= 10l;
- return(retval);
- }
-
-
- void rnormalize(struct rdiv_t *r1, struct rdiv_t *r2) /* normalize emulated fp values (fix the decimal places) */
- {
- extern int _r_minpre, _r_maxpre;
- extern boolean _r_maximum;
- struct rdiv_t *r;
- int i;
-
- _r_minpre = min(r1->precision,r2->precision);
- _r_maxpre = max(r1->precision,r2->precision);
- i = r1->precision - r2->precision;
- if (i == 0)
- return;
- if (i < 0) {
- i = -i;
- r = (_r_maximum) ? r1 : r2;
- } else
- r = (_r_maximum) ? r2 : r1;
- if (_r_maximum) /* adjust to largest amount of precision (extend) */
- for (; i>0; i--) {
- r->rfrac *= 10l;
- r->precision++;
- }
- else /* adjust to smallest amount of precision (truncate) */
- for (; i>0; i--) {
- r->rfrac /= 10l;
- r->precision--;
- }
- }
-
-
- long lpow(long base, int exponent) /* raise a base to an exponent */
- {
- long retval;
-
- for(retval = 1l; exponent > 0; exponent--)
- retval *= base;
- return(retval);
- }
- #endif
-