home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 January / usenetsourcesnewsgroupsinfomagicjanuary1994.iso / sources / unix / volume27 / calc-2.9.0 / part01 < prev    next >
Encoding:
Text File  |  1993-12-07  |  59.5 KB  |  1,892 lines

  1. Newsgroups: comp.sources.unix
  2. From: dbell@canb.auug.org.au (David I. Bell)
  3. Subject: v27i128: calc-2.9.0 - arbitrary precision C-like programmable calculator, Part01/19
  4. References: <1.755316719.21314@gw.home.vix.com>
  5. Sender: unix-sources-moderator@gw.home.vix.com
  6. Approved: vixie@gw.home.vix.com
  7.  
  8. Submitted-By: dbell@canb.auug.org.au (David I. Bell)
  9. Posting-Number: Volume 27, Issue 128
  10. Archive-Name: calc-2.9.0/part01
  11.  
  12. #!/bin/sh
  13. # shar:    Shell Archiver  (v1.22)
  14. #
  15. # This is part 1 of a multipart archive                                    
  16. # do not concatenate these parts, unpack them in order with /bin/sh        
  17. #
  18. #    Run the following text with /bin/sh to create:
  19. #      calc2.9.0/README
  20. #      calc2.9.0/CHANGES
  21. #      calc2.9.0/LIBRARY
  22. #      calc2.9.0/Makefile
  23. #      calc2.9.0/addop.c
  24. #      calc2.9.0/alloc.c
  25. #      calc2.9.0/alloc.h
  26. #      calc2.9.0/assocfunc.c
  27. #      calc2.9.0/calc.c
  28. #      calc2.9.0/calc.h
  29. #      calc2.9.0/calc.man
  30. #      calc2.9.0/cmath.h
  31. #      calc2.9.0/codegen.c
  32. #      calc2.9.0/comfunc.c
  33. #      calc2.9.0/commath.c
  34. #      calc2.9.0/config.c
  35. #      calc2.9.0/const.c
  36. #      calc2.9.0/endian.c
  37. #      calc2.9.0/file.c
  38. #      calc2.9.0/func.c
  39. #      calc2.9.0/func.h
  40. #      calc2.9.0/hist.c
  41. #      calc2.9.0/hist.h
  42. #      calc2.9.0/input.c
  43. #      calc2.9.0/label.c
  44. #      calc2.9.0/label.h
  45. #      calc2.9.0/lint.sed
  46. #      calc2.9.0/listfunc.c
  47. #      calc2.9.0/matfunc.c
  48. #      calc2.9.0/obj.c
  49. #      calc2.9.0/opcodes.c
  50. #      calc2.9.0/opcodes.h
  51. #      calc2.9.0/qfunc.c
  52. #      calc2.9.0/qio.c
  53. #      calc2.9.0/qmath.c
  54. #      calc2.9.0/qmath.h
  55. #      calc2.9.0/qmod.c
  56. #      calc2.9.0/qtrans.c
  57. #      calc2.9.0/stdarg.h
  58. #      calc2.9.0/string.c
  59. #      calc2.9.0/string.h
  60. #      calc2.9.0/symbol.c
  61. #      calc2.9.0/symbol.h
  62. #      calc2.9.0/token.c
  63. #      calc2.9.0/token.h
  64. #      calc2.9.0/value.c
  65. #      calc2.9.0/value.h
  66. #      calc2.9.0/version.c
  67. #      calc2.9.0/zfunc.c
  68. #      calc2.9.0/zio.c
  69. #      calc2.9.0/zmath.c
  70. #      calc2.9.0/zmath.h
  71. #      calc2.9.0/zmod.c
  72. #      calc2.9.0/zmul.c
  73. #      calc2.9.0/help/Makefile
  74. #      calc2.9.0/help/assoc
  75. #      calc2.9.0/help/builtin
  76. #      calc2.9.0/help/command
  77. #      calc2.9.0/help/config
  78. #      calc2.9.0/help/credit
  79. #      calc2.9.0/help/define
  80. #      calc2.9.0/help/environment
  81. #      calc2.9.0/help/expression
  82. #      calc2.9.0/help/file
  83. #      calc2.9.0/help/help
  84. #      calc2.9.0/help/history
  85. #      calc2.9.0/help/interrupt
  86. #      calc2.9.0/help/intro
  87. #      calc2.9.0/help/list
  88. #      calc2.9.0/help/mat
  89. #      calc2.9.0/help/obj.file
  90. #      calc2.9.0/help/operator
  91. #      calc2.9.0/help/overview
  92. #      calc2.9.0/help/statement
  93. #      calc2.9.0/help/todo
  94. #      calc2.9.0/help/types
  95. #      calc2.9.0/help/usage
  96. #      calc2.9.0/help/variable
  97. #      calc2.9.0/lib/Makefile
  98. #      calc2.9.0/lib/README
  99. #      calc2.9.0/lib/bernoulli.cal
  100. #      calc2.9.0/lib/bigprime.cal
  101. #      calc2.9.0/lib/bindings
  102. #      calc2.9.0/lib/chrem.cal
  103. #      calc2.9.0/lib/cryrand.cal
  104. #      calc2.9.0/lib/deg.cal
  105. #      calc2.9.0/lib/ellip.cal
  106. #      calc2.9.0/lib/lucas.cal
  107. #      calc2.9.0/lib/lucas_chk.cal
  108. #      calc2.9.0/lib/lucas_tbl.cal
  109. #      calc2.9.0/lib/mersenne.cal
  110. #      calc2.9.0/lib/mod.cal
  111. #      calc2.9.0/lib/nextprim.cal
  112. #      calc2.9.0/lib/pell.cal
  113. #      calc2.9.0/lib/pi.cal
  114. #      calc2.9.0/lib/pollard.cal
  115. #      calc2.9.0/lib/poly.cal
  116. #      calc2.9.0/lib/psqrt.cal
  117. #      calc2.9.0/lib/quat.cal
  118. #      calc2.9.0/lib/regress.cal
  119. #      calc2.9.0/lib/solve.cal
  120. #      calc2.9.0/lib/sumsq.cal
  121. #      calc2.9.0/lib/surd.cal
  122. #      calc2.9.0/lib/unitfrac.cal
  123. #      calc2.9.0/lib/varargs.cal
  124. #
  125. if test -r s2_seq_.tmp
  126. then echo "Must unpack archives in sequence!"
  127.      next=`cat s2_seq_.tmp`; echo "Please unpack part $next next"
  128.      exit 1; fi
  129. mkdir calc2.9.0
  130. mkdir calc2.9.0/help
  131. mkdir calc2.9.0/lib
  132. echo "x - extracting calc2.9.0/README (Text)"
  133. sed 's/^X//' << 'SHAR_EOF' > calc2.9.0/README &&
  134. X
  135. X# Copyright (c) 1993 David I. Bell
  136. X# Permission is granted to use, distribute, or modify this source,
  137. X# provided that this copyright notice remains intact.
  138. X#
  139. X# Arbitrary precision calculator.
  140. X
  141. XI am allowing this calculator to be freely distributed for personal uses.
  142. XLike all multi-precision programs, you should not depend absolutely on
  143. Xits results, since bugs in such programs can be insidious and only rarely 
  144. Xshow up.
  145. X  
  146. X-dbell-
  147. X
  148. Xp.s. By Landon Curt Noll
  149. X
  150. XTo build calc:
  151. X
  152. X    1) Look at the makefile, and adjust it to suit your needs.
  153. X
  154. X    2) build some calc documentation:
  155. X
  156. X    (cd help; make full)    <- after this, read the file help/full
  157. X
  158. X    3) build calc:
  159. X
  160. X    make
  161. X
  162. X    4) test calc:
  163. X
  164. X    After you have built calc, you can test it by running calc and 
  165. X    giving calc the following input:
  166. X
  167. X    read lib/regress    <- should produce no error messages
  168. X    read lib/lucas
  169. X    read lib/lucas_chk
  170. X    lucas_chk(200)        <- should produce no error messages
  171. X    exit
  172. X
  173. XIf you find bugs, or better yet have bug fixes; or if you have suggested
  174. Xchanges, or better yet have patches, send them to both myself and DBell:
  175. X
  176. X    dbell@canb.auug.org.au
  177. X    chongo@toad.com            {uunet,pyramid,sun}!hoptoad!chongo
  178. X
  179. XThe file doc/todo section points out some needs for calc.  Suggestions
  180. Xon other enhancements, and help in doing these are welcome.
  181. SHAR_EOF
  182. chmod 0644 calc2.9.0/README || echo "restore of calc2.9.0/README fails"
  183. set `wc -c calc2.9.0/README`;Sum=$1
  184. if test "$Sum" != "1304"
  185. then echo original size 1304, current size $Sum;fi
  186. echo "x - extracting calc2.9.0/CHANGES (Text)"
  187. sed 's/^X//' << 'SHAR_EOF' > calc2.9.0/CHANGES &&
  188. XFollowing is a list of visible changes to calc from version 1.27.0 to 2.9.0:
  189. X
  190. X    Full prototypes have been provided for all C functions, and are used
  191. X    if calc is compiled with an ANSI compiler.
  192. X
  193. X    Newly defined variables are now initialized to the value of zero instead
  194. X    of to the null value.  The elements of new objects are also initialized
  195. X    to the value of zero instead of null.
  196. X
  197. X    The gcd, lcm, and ismult functions now work for fractional values.
  198. X
  199. X    A major bug in the // division for fractions with a negative divisor
  200. X    was fixed.
  201. X
  202. X    A major bug in the calculation of ln for small values was fixed.
  203. X
  204. X    A major bug in the calculation of the ln and power functions for complex
  205. X    numbers was fixed.
  206. X
  207. X    A major lack of precision for sin and tan for small values was fixed.
  208. X
  209. X    A major lack of precision for complex square roots was fixed.
  210. X
  211. X    The "static" keyword has been implemented for variables.  So permanent
  212. X    variables can be defined to have either file scope or function scope.
  213. X
  214. X    Initialization of variables during their declaration are now allowed.
  215. X    This is most convenient for the initialization of static variables.
  216. X
  217. X    The matrix definition statement can now be used within a declaration
  218. X    statement, to immediately define a variable as a matrix.
  219. X
  220. X    Initializations of the elements of matrices are now allowed.  One-
  221. X    dimensional matrices may have implicit bounds when initialization is
  222. X    used.
  223. X
  224. X    The obj definition statement can now be used within a declaration
  225. X    statement, to immediately define a variable as an object.
  226. X
  227. X    Object definitions can be repeated as long as they are exactly the same
  228. X    as the previous definition.  This allows the rereading of files which
  229. X    happen to define objects.
  230. X
  231. X    The integer, rational, and complex routines have been made into a
  232. X    'libcalc.a' library so that they can be used in other programs besides
  233. X    the calculator.  The "math.h" include file has been split into three
  234. X    include files: "zmath.h", "qmath.h", and "cmath.h".
  235. X
  236. XFollowing is a list of visible changes to calc from version 1.26.4 to 1.27.0:
  237. X
  238. X    Added an assoc function to return a new type of value called an
  239. X    association.  Such values are indexed by one or more arbitrary values.
  240. X    They are stored in a hash table for quick access.
  241. X
  242. X    Added a hash() function which accepts one or more values and returns
  243. X    a quickly calculated small non-negative hash value for those values.
  244. X
  245. XFollowing is a list of visible changes to calc from version 1.26.2 to 1.26.4:
  246. X
  247. X    Misc fixes to Makefiles.
  248. X
  249. X    Misc lint fixes.
  250. X
  251. X    Misc portability fixes.
  252. X
  253. X    Misc typo and working fixes to comments, help files and the man page.
  254. X
  255. XFollowing is a list of visible changes to calc from version 1.24.7 to 1.26.2:
  256. X
  257. X    There is a new emacs-like command line editing and edit history
  258. X    feature.  The old history mechanism has been removed.  The key
  259. X    bindings for the new editing commands are slightly configurable
  260. X    since they are read in from an initialization file.  This file is
  261. X    usually called /usr/lib/calc/bindings, but can be changed by the
  262. X    CALCBINDINGS environment variable.  All editing code is
  263. X    self-contained in the new files hist.c and hist.h, which can be
  264. X    easily extracted and used in other programs.
  265. X
  266. X    Two new library files have been added: chrem.cal and cryrand.cal.
  267. X    The first of these solves the chinese remainder problem for a set
  268. X    of modulos and remainders.  The second of these implements several
  269. X    very good random number generators for large numbers.
  270. X
  271. X    A small bug which allowed division by zero was fixed.
  272. X
  273. X    A major bug in the mattrans function was fixed.
  274. X
  275. X    A major bug in the acos function for negative arguments was fixed.
  276. X
  277. X    A major bug in the strprintf function when objects were being printed
  278. X    was fixed.
  279. X
  280. X    A small bug in the library file regress.cal was fixed.
  281. SHAR_EOF
  282. chmod 0644 calc2.9.0/CHANGES || echo "restore of calc2.9.0/CHANGES fails"
  283. set `wc -c calc2.9.0/CHANGES`;Sum=$1
  284. if test "$Sum" != "3906"
  285. then echo original size 3906, current size $Sum;fi
  286. echo "x - extracting calc2.9.0/LIBRARY (Text)"
  287. sed 's/^X//' << 'SHAR_EOF' > calc2.9.0/LIBRARY &&
  288. X    USING THE ARBITRARY PRECISION ROUTINES IN A C PROGRAM
  289. X
  290. X
  291. XPart of the calc release consists of an arbitrary precision math library.
  292. XThis library is used by the calc program to perform its own calculations.
  293. XIf you wish, you can ignore the calc program entirely and call the arbitrary
  294. Xprecision math routines from your own C programs.
  295. X
  296. XThe library is called libmath.a, and provides routines to handle arbitrary
  297. Xprecision arithmetic with integers, rational numbers, or complex numbers.
  298. XThere are also many numeric functions such as factorial and gcd, along
  299. Xwith some transcendental functions such as sin and exp.
  300. X
  301. X-------------
  302. XINCLUDE FILES
  303. X-------------
  304. X
  305. XTo use any of these routines in your own programs, you need to include the
  306. Xappropriate include file.  These include files are:
  307. X
  308. X    zmath.h        (for integer arithmetic)
  309. X    qmath.h        (for rational arithmetic)
  310. X    cmath.h        (for complex number arithmetic)
  311. X
  312. XYou never need to include more than one of the above files, even if you wish
  313. Xto use more than one type of arithmetic, since qmath.h automatically includes
  314. Xzmath.h, and cmath.h automatically includes qmath.h.
  315. X
  316. XThe prototypes for the available routines are listed in the above include
  317. Xfiles.  Some of these routines are meant for internal use, and so aren't
  318. Xconvenient for outside use.  So you should read the source for a routine
  319. Xto see if it really does what you think it does.  I won't guarantee that
  320. Xobscure internal routines won't change or disappear in future releases!
  321. X
  322. XWhen calc is installed, all of the include files needed to build
  323. Xlibcalc.a along with the library itself (and the lint library
  324. Xllib-lcalc.ln, if made) are installed into ${LIBDIR}.
  325. X
  326. XExternal programgs may want to compile with:
  327. X    
  328. X    -I${LIBDIR} -L${LIBDIR} -lcalc
  329. X
  330. X--------------
  331. XERROR HANDLING
  332. X--------------
  333. X
  334. XYou program MUST provide a function called math_error.  This is called by
  335. Xthe math routines on an error condition, such as malloc failures or a
  336. Xdivision by zero.  The routine is called in the manner of printf, with a
  337. Xformat string and optional arguments.  (However, none of the low level math
  338. Xroutines currently uses formatting, so if you are lazy you can simply use
  339. Xthe first argument as a simple error string.)  For example, one of the
  340. Xerror calls you might expect to receive is:
  341. X
  342. X    math_error("Division by zero");
  343. X
  344. XYour program can handle errors in basically one of two ways.  Firstly, it
  345. Xcan simply print the error message and then exit.  Secondly, you can make
  346. Xuse of setjmp and longjmp in your program.  Use setjmp at some appropriate
  347. Xlevel in your program, and use longjmp in the math_error routine to return
  348. Xto that level and so recover from the error.  This is what the calc program
  349. Xdoes.
  350. X
  351. X---------------
  352. XOUTPUT ROUTINES
  353. X---------------
  354. X
  355. XThe output from the routines in the library normally goes to stdout.  You
  356. Xcan divert that output to either another FILE handle, or else to a string.
  357. XRead the routines in zio.c to see what is available.  Diversions can be
  358. Xnested.
  359. X
  360. XYou use math_setfp to divert output to another FILE handle.  Calling
  361. Xmath_setfp with stdout restores output to stdout.
  362. X
  363. XUse math_divertio to begin diverting output into a string.  Calling
  364. Xmath_getdivertedio will then return a string containing the output, and
  365. Xclears the diversion.  The string is reallocated as necessary, but since
  366. Xit is in memory, there are obviously limits on the amount of data that can
  367. Xbe diverted into it.  The string needs freeing when you are done with it.
  368. X
  369. XCalling math_cleardiversions will clear all the diversions to strings, and
  370. Xis useful on an error condition to restore output to a known state.  You
  371. Xshould also call math_setfp on errors if you had changed that.
  372. X
  373. XIf you wish to mix your own output with numeric output from the math routines,
  374. Xthen you can call math_chr, math_str, math_fill, math_fmt, or math_flush.
  375. XThese routines output single characters, output null-terminated strings,
  376. Xoutput strings with space filling, output formatted strings like printf, and
  377. Xflush the output.  Output from these routines is diverted as described above.
  378. X
  379. XYou can change the default output mode by calling math_setmode, and you can
  380. Xchange the default number of digits printed by calling math_setdigits.  These
  381. Xroutines return the previous values.  The possible modes are described in
  382. Xzmath.h.
  383. X
  384. X--------------
  385. XUSING INTEGERS
  386. X--------------
  387. X
  388. XThe arbitrary precision integer routines define a structure called a ZVALUE.
  389. XThis is defined in zmath.h.  A ZVALUE contains a pointer to an array of
  390. Xintegers, the length of the array, and a sign flag.  The array is allocated
  391. Xusing malloc, so you need to free this array when you are done with a
  392. XZVALUE.  To do this, you should call zfree with the ZVALUE as an argument
  393. X(or call freeh with the pointer as an argument) and never try to free the
  394. Xarray yourself using free.  The reason for this is that sometimes the pointer
  395. Xpoints to one of two statically allocated arrays which should NOT be freed.
  396. X
  397. XThe ZVALUE structures are passed to routines by value, and are returned
  398. Xthrough pointers.  For example, to multiply two small integers together,
  399. Xyou could do the following:
  400. X
  401. X    ZVALUE    z1, z2, z3;
  402. X
  403. X    itoz(3L, &z1);
  404. X    itoz(4L, &z2);
  405. X    zmul(z1, z2, &z3);
  406. X
  407. XUse zcopy to copy one ZVALUE to another.  There is no sharing of arrays
  408. Xbetween different ZVALUEs even if they have the same value, so you MUST
  409. Xuse this routine.  Simply assigning one value into another will cause
  410. Xproblems when one of the copies is freed.  However, the special ZVALUE
  411. Xvalues _zero_ and _one_ CAN be assigned to variables directly, since their
  412. Xvalues of 0 and 1 are so common that special checks are made for them.
  413. X
  414. XFor initial values besides 0 or 1, you need to call itoz to convert a long
  415. Xvalue into a ZVALUE, as shown in the above example.  Or alternatively,
  416. Xfor larger numbers you can use the atoz routine to convert a string which
  417. Xrepresents a number into a ZVALUE.  The string can be in decimal, octal,
  418. Xhex, or binary according to the leading digits.
  419. X
  420. XAlways make sure you free a ZVALUE when you are done with it or when you
  421. Xare about to overwrite an old ZVALUE with another value by passing its
  422. Xaddress to a routine as a destination value, otherwise memory will be
  423. Xlost.  The following shows an example of the correct way to free memory
  424. Xover a long sequence of operations.
  425. X
  426. X    ZVALUE z1, z2, z3;
  427. X
  428. X    z1 = _one_;
  429. X    atoz("12345678987654321", &z2);
  430. X    zadd(z1, z2, &z3);
  431. X    zfree(z1);
  432. X    zfree(z2);
  433. X    zsquare(z3, &z1);
  434. X    zfree(z3);
  435. X    itoz(17L, &z2);
  436. X    zsub(z1, z2, &z3);
  437. X    zfree(z1);
  438. X    zfree(z2);
  439. X    zfree(z3);
  440. X
  441. XThere are some quick checks you can make on integers.  For example, whether
  442. Xor not they are zero, negative, even, and so on.  These are all macros
  443. Xdefined in zmath.h, and should be used instead of checking the parts of the
  444. XZVALUE yourself.  Examples of such checks are:
  445. X
  446. X    ziseven(z)    (number is even)
  447. X    zisodd(z)    (number is odd)
  448. X    ziszero(z)    (number is zero)
  449. X    zisneg(z)    (number is negative)
  450. X    zispos(z)    (number is positive)
  451. X    zisunit(z)    (number is 1 or -1)
  452. X    zisone(z)    (number is 1)
  453. X
  454. XThere are two types of comparisons you can make on ZVALUEs.  This is whether
  455. Xor not they are equal, or the ordering on size of the numbers.  The zcmp
  456. Xfunction tests whether two ZVALUEs are equal, returning TRUE if they differ.
  457. XThe zrel function tests the relative sizes of two ZVALUEs, returning -1 if
  458. Xthe first one is smaller, 0 if they are the same, and 1 if the first one
  459. Xis larger.
  460. X
  461. X---------------
  462. XUSING FRACTIONS
  463. X---------------
  464. X
  465. XThe arbitrary precision fractional routines define a structure called NUMBER.
  466. XThis is defined in qmath.h.  A NUMBER contains two ZVALUEs for the numerator
  467. Xand denominator of a fraction, and a count of the number of uses there are
  468. Xfor this NUMBER.  The numerator and denominator are always in lowest terms,
  469. Xand the sign of the number is contained in the numerator.  The denominator
  470. Xis always positive.  If the NUMBER is an integer, the denominator has the
  471. Xvalue 1.
  472. X
  473. XUnlike ZVALUEs, NUMBERs are passed using pointers, and pointers to them are
  474. Xreturned by functions.  So the basic type for using fractions is not really
  475. X(NUMBER), but is (NUMBER *).  NUMBERs are allocated using the qalloc routine.
  476. XThis returns a pointer to a number which has the value 1.  Because of the
  477. Xspecial property of a ZVALUE of 1, the numerator and denominator of this
  478. Xreturned value can simply be overwritten with new ZVALUEs without needing
  479. Xto free them first.  The following illustrates this:
  480. X
  481. X    NUMBER *q;
  482. X
  483. X    q = qalloc();
  484. X    itoz(55L, &q->num);
  485. X
  486. XA better way to create NUMBERs with particular values is to use the itoq,
  487. Xiitoq, or atoq functions.  Using itoq makes a long value into a NUMBER,
  488. Xusing iitoq makes a pair of longs into the numerator and denominator of a
  489. XNUMBER (reducing them first if needed), and atoq converts a string representing
  490. Xa number into the corresponding NUMBER.  The atoq function accepts input in
  491. Xintegral, fractional, real, or exponential formats.  Examples of allocating
  492. Xnumbers are:
  493. X
  494. X    NUMBER *q1, *q2, *q3;
  495. X
  496. X    q1 = itoq(66L);
  497. X    q2 = iitoq(2L, 3L);
  498. X    q3 = atoq("456.78");
  499. X
  500. XAlso unlike ZVALUEs, NUMBERs are quickly copied.  This is because they contain
  501. Xa link count, which is the number of pointers there are to the NUMBER.  The
  502. Xqlink macro is used to copy a pointer to a NUMBER, and simply increments
  503. Xthe link count and returns the same pointer.  Since it is a macro, the
  504. Xargument should not be a function call, but a real pointer variable.  The
  505. Xqcopy routine will actually make a new copy of a NUMBER, with a new link
  506. Xcount of 1.  This is not usually needed.
  507. X
  508. XNUMBERs are deleted using the qfree routine.  This decrements the link count
  509. Xin the NUMBER, and if it reaches zero, then it will deallocate both of
  510. Xthe ZVALUEs contained within the NUMBER, and then puts the NUMBER structure
  511. Xonto a free list for quick reuse.  The following is an example of allocating
  512. XNUMBERs, copying them, adding them, and finally deleting them again.
  513. X
  514. X    NUMBER *q1, *q2, *q3;
  515. X
  516. X    q1 = itoq(111L);
  517. X    q2 = qlink(q1);
  518. X    q3 = qadd(q1, q2);
  519. X    qfree(q1);
  520. X    qfree(q2);
  521. X    qfree(q3);
  522. X
  523. XBecause of the passing of pointers and the ability to copy numbers easily,
  524. Xyou might wish to use the rational number routines even for integral
  525. Xcalculations.  They might be slightly slower than the raw integral routines,
  526. Xbut are more convenient to program with.
  527. X
  528. XThe prototypes for the fractional routines are defined in qmath.h.
  529. XMany of the definitions for integer functions parallel the ones defined
  530. Xin zmath.h.  But there are also functions used only for fractions.
  531. XExamples of these are qnum to return the numerator, qden to return the
  532. Xdenominator, qint to return the integer part of, qfrac to return the
  533. Xfractional part of, and qinv to invert a fraction.
  534. X
  535. XThere are some transcendental functions in the library, such as sin and cos.
  536. XThese cannot be evaluated exactly as fractions.  Therefore, they accept
  537. Xanother argument which tells how accurate you want the result.  This is an
  538. X"epsilon" value, and the returned value will be within that quantity of
  539. Xthe correct value.  This is usually an absolute difference, but for some
  540. Xfunctions (such as exp), this is a relative difference.  For example, to
  541. Xcalculate sin(0.5) to 100 decimal places, you could do:
  542. X
  543. X    NUMBER *q, *ans, *epsilon;
  544. X
  545. X    q = atoq("0.5");
  546. X    epsilon = atoq("1e-100");
  547. X    ans = qsin(q, epsilon);
  548. X
  549. XThere are many convenience macros similar to the ones for ZVALUEs which can
  550. Xgive quick information about NUMBERs.  In addition, there are some new ones
  551. Xapplicable to fractions.  These are all defined in qmath.h.  Some of these
  552. Xmacros are:
  553. X
  554. X    qiszero(q)    (number is zero)
  555. X    qisneg(q)    (number is negative)
  556. X    qispos(q)    (number is positive)
  557. X    qisint(q)    (number is an integer)
  558. X    qisfrac(q)    (number is fractional)
  559. X    qisunit(q)    (number is 1 or -1)
  560. X    qisone(q)    (number is 1)
  561. X
  562. XThe comparisons for NUMBERs are similar to the ones for ZVALUEs.  You use the
  563. Xqcmp and qrel functions.
  564. X
  565. XThere are four predefined values for fractions.  You should qlink them when
  566. Xyou want to use them.  These are _qzero_, _qone_, _qnegone_, and _qonehalf_.
  567. XThese have the values 0, 1, -1, and 1/2.  An example of using them is:
  568. X
  569. X    NUMBER *q1, *q2;
  570. X
  571. X    q1 = qlink(&_qonehalf_);
  572. X    q2 = qlink(&_qone_);
  573. X
  574. X---------------------
  575. XUSING COMPLEX NUMBERS
  576. X---------------------
  577. X
  578. XThe arbitrary precision complex arithmetic routines define a structure
  579. Xcalled COMPLEX.  This is defined in cmath.h.  This contains two NUMBERs
  580. Xfor the real and imaginary parts of a complex number, and a count of the
  581. Xnumber of links there are to this COMPLEX number.
  582. X
  583. XThe complex number routines work similarly to the fractional routines.
  584. XYou can allocate a COMPLEX structure using comalloc (NOT calloc!).
  585. XYou can construct a COMPLEX number with desired real and imaginary
  586. Xfractional parts using qqtoc.  You can copy COMPLEX values using clink
  587. Xwhich increments the link count.  And you free a COMPLEX value using cfree.
  588. XThe following example illustrates this:
  589. X
  590. X    NUMBER *q1, *q2;
  591. X    COMPLEX *c1, *c2, *c3;
  592. X
  593. X    q1 = itoq(3L);
  594. X    q2 = itoq(4L);
  595. X    c1 = qqtoc(q1, q2);
  596. X    qfree(q1);
  597. X    qfree(q2);
  598. X    c2 = clink(c1);
  599. X    c3 = cmul(c1, c2);
  600. X    cfree(c1);
  601. X    cfree(c2);
  602. X    cfree(c3);
  603. X
  604. XAs a shortcut, when you want to manipulate a COMPLEX value by a real value,
  605. Xyou can use the caddq, csubq, cmulq, and cdivq routines.  These accept one
  606. XCOMPLEX value and one NUMBER value, and produce a COMPLEX value.
  607. X
  608. XThere is no direct routine to convert a string value into a COMPLEX value.
  609. XBut you can do this yourself by converting two strings into two NUMBERS,
  610. Xand then using the qqtoc routine.
  611. X
  612. XCOMPLEX values are always returned from these routines.  To split out the
  613. Xreal and imaginary parts into normal NUMBERs, you can simply qlink the
  614. Xtwo components, as shown in the following example:
  615. X
  616. X    COMPLEX *c;
  617. X    NUMBER *rp, *ip;
  618. X
  619. X    c = calloc();
  620. X    rp = qlink(c->real);
  621. X    ip = qlink(c->imag);
  622. X
  623. XThere are many macros for checking quick things about complex numbers,
  624. Xsimilar to the ZVALUE and NUMBER macros.  In addition, there are some
  625. Xonly used for complex numbers.  Examples of macros are:
  626. X
  627. X    cisreal(c)    (number is real)
  628. X    cisimag(c)    (number is pure imaginary)
  629. X    ciszero(c)    (number is zero)
  630. X    cisrunit(c)    (number is 1 or -1)
  631. X    cisiunit(c)    (number is i or -i)
  632. X    cisunit(c)    (number is 1, -1, i, or -i)
  633. X
  634. XThere is only one comparison you can make for COMPLEX values, and that is
  635. Xfor equality.  The ccmp function returns TRUE if two complex numbers differ.
  636. X
  637. XThere are three predefined values for complex numbers.  You should clink
  638. Xthem when you want to use them.  They are _czero_, _cone_, and _conei_.
  639. XThese have the values 0, 1, and i.
  640. SHAR_EOF
  641. chmod 0444 calc2.9.0/LIBRARY || echo "restore of calc2.9.0/LIBRARY fails"
  642. set `wc -c calc2.9.0/LIBRARY`;Sum=$1
  643. if test "$Sum" != "14396"
  644. then echo original size 14396, current size $Sum;fi
  645. echo "x - extracting calc2.9.0/Makefile (Text)"
  646. sed 's/^X//' << 'SHAR_EOF' > calc2.9.0/Makefile &&
  647. X#
  648. X# Copyright (c) 1993 David I. Bell and Landon Curt Noll
  649. X# Permission is granted to use, distribute, or modify this source,
  650. X# provided that this copyright notice remains intact.
  651. X#
  652. X# Arbitrary precision calculator.
  653. X#
  654. X# calculator by David I. Bell
  655. X# makefile by Landon Curt Noll
  656. X
  657. X##############################################################################
  658. X#-=-=-=-=-=-=-=-=- You may want to change some values below -=-=-=-=-=-=-=-=-#
  659. X##############################################################################
  660. X
  661. X# Determine the type of terminal controls that you want to use
  662. X#
  663. X#    VARARG value      meaning
  664. X#    ------------      -------
  665. X#    (nothing)      let the makefile guess at what you need
  666. X#    -DUSE_TERMIOS      use struct termios from <termios.h>
  667. X#    -DUSE_TERMIO       use struct termios from <termio.h>
  668. X#    -DUSE_SGTTY          use struct sgttyb from <sys/ioctl.h>
  669. X#
  670. XTERMCONTROL=
  671. X#TERMCONTROL= -DUSE_TERMIOS
  672. X#TERMCONTROL= -DUSE_TERMIO
  673. X#TERMCONTROL= -DUSE_SGTTY
  674. X
  675. X# Determine the type of varargs that you want to use
  676. X#
  677. X#    VARARG value      meaning
  678. X#    ------------      -------
  679. X#    (nothing)      let the makefile guess at what you need
  680. X#    STDARG              you have ANSI C and /usr/include/stdarg.h
  681. X#    VARARGS              you have /usr/include/varargs.h
  682. X#    SIMULATE_STDARG   use simulated ./stdarg.h
  683. X#
  684. X# Try defining VARARG to be nothing.  The makefile will look for the
  685. X# needed .h files, trying for stdarg.h first.
  686. X#
  687. XVARARG=
  688. X#VARARG= STDARG
  689. X#VARARG= VARARGS
  690. X#VARARG= SIMULATE_STDARG
  691. X
  692. X# If your system does not have a vsprintf() function, you could be in trouble.
  693. X#
  694. X#    vsprintf(stream, format, ap)
  695. X#
  696. X# This function works like sprintf except that the 3rd arg is a va_list
  697. X# strarg (or varargs) list.
  698. X#
  699. X# If you have vsprintf, then define DONT_HAVE_VSPRINTF to be an empty string.
  700. X# Some old systems do not have vsprintf().  If you do not have vsprintf()
  701. X# then define DONT_HAVE_VSPRINTF to be -DDONT_HAVE_VSPRINTF and hope for
  702. X# the best.
  703. X#
  704. XDONT_HAVE_VSPRINTF=
  705. X#DONT_HAVE_VSPRINTF= -DDONT_HAVE_VSPRINTF
  706. X
  707. X# Determine the byte order of your machine
  708. X#
  709. X#    Big Endian:    Amdahl, 68k, Pyramid, Mips, Sparc, ...
  710. X#    Little Endian:    Vax, 32k, Spim (Dec Mips), i386, i486, ...
  711. X#
  712. X# If in doubt, leave BYTE_ORDER empty.  This makefile will attempt to
  713. X# use BYTE_ORDER in <machine/endian.h> or it will attempt to run
  714. X# the endian program.  If you get syntax errors when you compile,
  715. X# try forcing the value to be BIG_ENDIAN and run the calc regression
  716. X# tests. (see the README file)  If the calc regression tests fail, do
  717. X# a make clobber and try LITTLE_ENDIAN.  If that fails, ask a wizard
  718. X# for help.
  719. X#
  720. XBYTE_ORDER=
  721. X#BYTE_ORDER= BIG_ENDIAN
  722. X#BYTE_ORDER= LITTLE_ENDIAN
  723. X
  724. X# Determine whether to use the standard malloc or the alternative one
  725. X# included with the calculator.  On some machines, the alternative malloc
  726. X# may be faster.  It also can help to debug malloc problems.
  727. X#
  728. X# Define MALLOC to be -DCALC_MALLOC to use the internal malloc routines.
  729. X#
  730. X# If in doubt, leave MALLOC empty.
  731. X#
  732. XMALLOC=
  733. X#MALLOC= -DCALC_MALLOC
  734. X
  735. X# where to install binary files
  736. X#
  737. XBINDIR= /usr/bin
  738. X#BINDIR= /usr/local/bin
  739. X
  740. X# where to install the lib/*.cal files
  741. X#
  742. XLIBDIR= /usr/lib/calc
  743. X#LIBDIR= /usr/local/lib/calc
  744. X
  745. X# where to install help files
  746. X#
  747. X# The ${LIBDIR}/help is where the help files will be installed.
  748. X#
  749. XHELPDIR= ${LIBDIR}/help
  750. X
  751. X# where man pages are installed
  752. X#
  753. XMANDIR=/usr/man/man1
  754. X#MANDIR=/usr/local/man/man1
  755. X#MANDIR=/usr/share/man/man1
  756. X#MANDIR=/usr/man/u_man/man1
  757. X
  758. X# If the $CALCPATH environment variable is not defined, then the following
  759. X# path will be search for calc lib routines.
  760. X#
  761. XCALCPATH= .:./lib:~/lib:${LIBDIR}
  762. X
  763. X# If the $CALCRC environment variable is not defined, then the following
  764. X# path will be search for calc lib routines.
  765. X#
  766. XCALCRC= ${LIBDIR}/startup:~/.calcrc
  767. X
  768. X# If the $CALCBINDINGS environment variable is not defined, then the following
  769. X# file will be used for the command line and edit history key bindings.
  770. X#
  771. XCALCBINDINGS= ${LIBDIR}/bindings
  772. X
  773. X# If $PAGER is not set, use this program to display a help file
  774. X#
  775. XCALCPAGER= more
  776. X#CALCPAGER= less
  777. X#CALCPAGER= pg
  778. X#CALCPAGER= cat
  779. X
  780. X# Compile debug options
  781. X#
  782. X# Select -O, or empty string, if you don't want to debug
  783. XDEBUG= -O
  784. X#DEBUG= -O3
  785. X#DEBUG= -g
  786. X#DEBUG= -gx
  787. X#DEBUG= -WM,-g
  788. X#DEBUG=
  789. X
  790. X# On systems that have dynamic shared libs, you want want to disable them
  791. X# for faster calc startup.
  792. X#
  793. XNO_SHARED=
  794. X#NO_SHARED= -dn
  795. X
  796. X# Some systems allow 'mkdir -p' to make a directory and any needed parent
  797. X# directories.
  798. X#
  799. X# If you system has 'mkdir -p', then:    MKDIR=mkdir -p
  800. X# otherwise:                MKDIR=mkdir
  801. X#
  802. X# If you do not have 'mkdir -p', then you must ensure that ${LIBDIR},
  803. X# ${BINDIR} and ${HELPDIR} exist before you do an install.
  804. X#
  805. XMKDIR=mkdir -p
  806. X#MKDIR=mkdir
  807. X
  808. X# If you are running an an old BSD system, then you may not have
  809. X# the following functions:
  810. X#
  811. X#    memcpy()    strchr()    memset()
  812. X#
  813. X# If you do not have these functions, define OLD_BSD to be -DOLD_BSD,
  814. X# otherwise define OLD_BSD to be an empty string.
  815. X#
  816. X# Modern BSD and BSD-like systems have these functions and thus don't
  817. X# need OLD_BSD.  If you don't know, try using the empty string and if
  818. X# you get complaints, try -DOLD_BSD.
  819. X#
  820. XOLD_BSD=
  821. X#OLD_BSD= -DOLD_BSD
  822. X
  823. X# Some old systems don't know what a uid_t is.  Define UID_T if you get
  824. X# an error regarding 'uid_t' when compiling files such as calc.c
  825. X#
  826. XUID_T=
  827. X#UID_T= -DUID_T
  828. X
  829. X# Some systems require one to use ranlib to add a symbol table to
  830. X# a *.a library.  Set RANLIB to the utility that performs this action.
  831. X# Set RANLIB to : if your system does not need such a utility.
  832. X#
  833. X#RANLIB=ranlib
  834. XRANLIB=:
  835. X
  836. X# Some systems are able to form lint libs.  How it is formed depends
  837. X# on your system.  If you do not care about lint, use : as the
  838. X# LINTLIB value.
  839. X#
  840. X#    System type    LINTLIB recomendation
  841. X#
  842. X#    BSD        ${LINT} ${LCFLAGS} ${LINTFLAGS} -u -Ccalc
  843. X#    SYSV        ${LINT} ${LCFLAGS} ${LINTFLAGS} -u -o calc
  844. X#    disable     :
  845. X#
  846. XLINTLIB= ${LINT} ${LCFLAGS} ${LINTFLAGS} -u -Ccalc
  847. X#LINTLIB= ${LINT} ${LCFLAGS} ${LINTFLAGS} -u -o calc
  848. X#LINTLIB= :
  849. X
  850. X# The lint flags vary from system to system.  Some systems have the
  851. X# opposite meaning for the flags below.  Other systems change flag
  852. X# meaning altogether.
  853. X#
  854. X#       System    LINTFLAGS recomendation
  855. X#
  856. X#    SunOs      -a -h -v -z
  857. X#
  858. XLINTFLAGS= -a -h -v -z
  859. X#LINTFLAGS=
  860. X
  861. X##############################################################################
  862. X#-=-=-=-=-=-=-=-=- Be careful if you change something below -=-=-=-=-=-=-=-=-#
  863. X##############################################################################
  864. X
  865. X# standard utilities used during make
  866. X#
  867. XSHELL= /bin/sh
  868. XMAKE= make
  869. XSED= sed
  870. XTEE= tee
  871. XLINT= lint
  872. XCTAGS= ctags
  873. XCC= cc
  874. X#CC= gcc
  875. X
  876. X
  877. X#
  878. X# the source files which are built into a math library
  879. X#
  880. XLIBSRC = alloc.c comfunc.c commath.c qfunc.c qio.c qmath.c qmod.c qtrans.c \
  881. X    zfunc.c zio.c zmath.c zmod.c zmul.c
  882. X
  883. X
  884. X#
  885. X# the object files which are built into a math library
  886. X#
  887. XLIBOBJS = alloc.o comfunc.o commath.o qfunc.o qio.o qmath.o qmod.o qtrans.o \
  888. X    zfunc.o zio.o zmath.o zmod.o zmul.o
  889. X
  890. X#
  891. X# the calculator source files
  892. X#
  893. XCALCSRC = addop.c assocfunc.c calc.c codegen.c config.c const.c    file.c \
  894. X    func.c hist.c input.c label.c listfunc.c matfunc.c obj.c opcodes.c \
  895. X    string.c symbol.c token.c value.c version.c
  896. X
  897. X
  898. X#
  899. X# we build these .o files for calc
  900. X#
  901. XCALCOBJS = addop.o assocfunc.o calc.o codegen.o config.o const.o file.o \
  902. X    func.o hist.o input.o label.o listfunc.o matfunc.o obj.o opcodes.o \
  903. X    string.o symbol.o token.o value.o version.o
  904. X
  905. X
  906. X# we build these .h files during the make
  907. X#
  908. XBUILD_H_SRC= config.h have_malloc.h have_stdlib.h have_string.h args.h \
  909. X    args.h terminal.h endian.h
  910. X
  911. X
  912. X# these .h files are needed by programs that use libcalc.a
  913. X#
  914. XLIB_H_SRC= qmath.h zmath.h cmath.h alloc.h have_stdlib.h have_malloc.h \
  915. X    have_string.h endian.h
  916. X
  917. X
  918. X# The code program is not part of the calc distribution, don't worry
  919. X# if you do not have it.
  920. X#
  921. XCODEOBJS= code.o
  922. X
  923. X
  924. X# LCFLAGS are flags that both ${CC} and ${LINT} can use
  925. X# CFLAGS are the default flags given to ${CC}
  926. X#
  927. XLCFLAGS= ${MALLOC} ${OLD_BSD} ${DONT_HAVE_VSPRINTF} ${UID_T}
  928. XCFLAGS= ${DEBUG} ${LCFLAGS}
  929. X
  930. Xall: calc calc.1
  931. X
  932. Xcalc: libcalc.a ${CALCOBJS}
  933. X    ${CC} ${CFLAGS} ${CALCOBJS} libcalc.a -o calc ${NO_SHARED}
  934. X
  935. Xhist.o: hist.c Makefile
  936. X    ${CC} ${CFLAGS} ${DEBUG} ${TERMCONTROL} -c hist.c
  937. X
  938. Xlibcalc.a: ${LIBOBJS} Makefile
  939. X    rm -f libcalc.a
  940. X    ar qc libcalc.a ${LIBOBJS}
  941. X    ${RANLIB} libcalc.a
  942. X
  943. Xendian: endian.c
  944. X    -@rm -f endian.o endian
  945. X    ${CC} ${CFLAGS} endian.c -o endian ${NO_SHARED}
  946. X
  947. Xconfig.h: Makefile
  948. X    rm -f config.h
  949. X    @echo 'forming config.h'
  950. X    @echo '/*' > config.h
  951. X    @echo ' * DO NOT EDIT -- generated by the Makefile' >> config.h
  952. X    @echo ' */' >> config.h
  953. X    @echo '' >> config.h
  954. X    @echo '/* the default :-separated search path */' >> config.h
  955. X    @echo '#ifndef DEFAULTCALCPATH' >> config.h
  956. X    @echo '#define DEFAULTCALCPATH "${CALCPATH}"' >> config.h
  957. X    @echo '#endif /* DEFAULTCALCPATH */' >> config.h
  958. X    @echo '' >> config.h
  959. X    @echo '/* the default :-separated startup file list */' >> config.h
  960. X    @echo '#ifndef DEFAULTCALCRC' >> config.h
  961. X    @echo '#define DEFAULTCALCRC "${CALCRC}"' >> config.h
  962. X    @echo '#endif /* DEFAULTCALCRC */' >> config.h
  963. X    @echo '' >> config.h
  964. X    @echo '/* the default key bindings file */' >> config.h
  965. X    @echo '#ifndef DEFAULTCALCBINDINGS' >> config.h
  966. X    @echo '#define DEFAULTCALCBINDINGS "${CALCBINDINGS}"' >> config.h
  967. X    @echo '#endif /* DEFAULTCALCBINDINGS */' >> config.h
  968. X    @echo '' >> config.h
  969. X    @echo '/* the location of the help directory */' >> config.h
  970. X    @echo '#ifndef HELPDIR' >> config.h
  971. X    @echo '#define HELPDIR "${HELPDIR}"' >> config.h
  972. X    @echo '#endif /* HELPDIR */' >> config.h
  973. X    @echo '' >> config.h
  974. X    @echo '/* the default pager to use */' >> config.h
  975. X    @echo '#ifndef DEFAULTCALCPAGER' >> config.h
  976. X    @echo '#define DEFAULTCALCPAGER "${CALCPAGER}"' >> config.h
  977. X    @echo '#endif /* DEFAULTCALCPAGER */' >> config.h
  978. X    @echo 'config.h formed'
  979. X
  980. Xendian.h: endian
  981. X    rm -f endian.h
  982. X    @echo 'forming endian.h'
  983. X    @echo '/*' > endian.h
  984. X    @echo ' * DO NOT EDIT -- generated by the Makefile' >> endian.h
  985. X    @echo ' */' >> endian.h
  986. X    @echo '' >> endian.h
  987. X    -@if [ X"${BYTE_ORDER}" = X ]; then \
  988. X        if [ -f /usr/include/machine/endian.h ]; then \
  989. X        echo '#include <machine/endian.h>' >> endian.h; \
  990. X        else \
  991. X        ./endian >> endian.h; \
  992. X        fi; \
  993. X    else \
  994. X        echo "#define BYTE_ORDER ${BYTE_ORDER}" >> endian.h; \
  995. X    fi
  996. X    @echo 'endian.h formed'
  997. X
  998. Xhave_malloc.h: Makefile
  999. X    rm -f have_malloc.h
  1000. X    @echo 'forming have_malloc.h'
  1001. X    @echo '/*' > have_malloc.h
  1002. X    @echo ' * DO NOT EDIT -- generated by the Makefile' >> have_malloc.h
  1003. X    @echo ' */' >> have_malloc.h
  1004. X    @echo '' >> have_malloc.h
  1005. X    @echo '/* do we have /usr/include/malloc.h? */' > have_malloc.h
  1006. X    -@if [ -f /usr/include/malloc.h ]; then \
  1007. X        echo '#define HAVE_MALLOC_H  /* yes */' >> have_malloc.h; \
  1008. X    else \
  1009. X        echo '#undef HAVE_MALLOC_H   /* no */' >> have_malloc.h; \
  1010. X    fi
  1011. X    @echo 'have_malloc.h formed'
  1012. X
  1013. Xhave_stdlib.h: Makefile
  1014. X    rm -f have_stdlib.h
  1015. X    @echo 'forming have_stdlib.h'
  1016. X    @echo '/*' > have_stdlib.h
  1017. X    @echo ' * DO NOT EDIT -- generated by the Makefile' >> have_stdlib.h
  1018. X    @echo ' */' >> have_stdlib.h
  1019. X    @echo '' >> have_stdlib.h
  1020. X    @echo '/* do we have /usr/include/stdlib.h? */' > have_stdlib.h
  1021. X    -@if [ -f /usr/include/stdlib.h ]; then \
  1022. X        echo '#define HAVE_STDLIB_H  /* yes */' >> have_stdlib.h; \
  1023. X    else \
  1024. X        echo '#undef HAVE_STDLIB_H   /* no */' >> have_stdlib.h; \
  1025. X    fi
  1026. X    @echo 'have_stdlib.h formed'
  1027. X
  1028. Xhave_string.h: Makefile
  1029. X    rm -f have_string.h
  1030. X    @echo 'forming have_string.h'
  1031. X    @echo '/*' > have_string.h
  1032. X    @echo ' * DO NOT EDIT -- generated by the Makefile' >> have_string.h
  1033. X    @echo ' */' >> have_string.h
  1034. X    @echo '' >> have_string.h
  1035. X    @echo '/* do we have /usr/include/string.h? */' > have_string.h
  1036. X    -@if [ -f /usr/include/string.h ]; then \
  1037. X        echo '#define HAVE_STRING_H  /* yes */' >> have_string.h; \
  1038. X    else \
  1039. X        echo '#undef HAVE_STRING_H   /* no */' >> have_string.h; \
  1040. X    fi
  1041. X    @echo 'have_string.h formed'
  1042. X
  1043. Xterminal.h: Makefile
  1044. X    rm -f terminal.h
  1045. X    @echo 'forming terminal.h'
  1046. X    @echo '/*' > terminal.h
  1047. X    @echo ' * DO NOT EDIT -- generated by the Makefile' >> terminal.h
  1048. X    @echo ' */' >> terminal.h
  1049. X    @echo '' >> terminal.h
  1050. X    @echo '#if !defined(USE_TERMIOS)' >> terminal.h
  1051. X    @echo '#if !defined(USE_TERMIO)' >> terminal.h
  1052. X    @echo '#if !defined(USE_SGTTY)' >> terminal.h
  1053. X    -@if [ -f /usr/include/termios.h ]; then \
  1054. X        echo '#define USE_TERMIOS  /* <termios.h> */' >> terminal.h; \
  1055. X        echo '#undef USE_TERMIO    /* <termio.h> */' >> terminal.h; \
  1056. X        echo '#undef USE_SGTTY     /* <sys/ioctl.h> */' >> terminal.h; \
  1057. X    elif [ -f /usr/include/termio.h ]; then \
  1058. X        echo '#undef USE_TERMIOS   /* <termios.h> */' >> terminal.h; \
  1059. X        echo '#define USE_TERMIO   /* <termio.h> */' >> terminal.h; \
  1060. X        echo '#undef USE_SGTTY     /* <sys/ioctl.h> */' >> terminal.h; \
  1061. X    else \
  1062. X        echo '#undef USE_TERMIOS   /* <termios.h> */' >> terminal.h; \
  1063. X        echo '#undef USE_TERMIO    /* <termio.h> */' >> terminal.h; \
  1064. X        echo '#define USE_SGTTY    /* <sys/ioctl.h> */' >> terminal.h; \
  1065. X    fi
  1066. X    @echo '#endif' >> terminal.h
  1067. X    @echo '#endif' >> terminal.h
  1068. X    @echo '#endif' >> terminal.h
  1069. X    @echo 'terminal.h formed'
  1070. X
  1071. Xargs.h: Makefile
  1072. X    rm -f args.h
  1073. X    @echo 'forming args.h'
  1074. X    @echo '/*' > args.h
  1075. X    @echo ' * DO NOT EDIT -- generated by the Makefile' >> args.h
  1076. X    @echo ' */' >> args.h
  1077. X    @echo '' >> args.h
  1078. X    @echo '/* what sort of variable args do we have? */' > args.h
  1079. X    -@if [ ! -z "${VARARG}" ]; then \
  1080. X        echo '#define ${VARARG}' >> args.h; \
  1081. X    elif [ -f /usr/include/stdarg.h ]; then \
  1082. X        echo '#define STDARG' >> args.h; \
  1083. X    elif [ -f /usr/include/varargs.h ]; then \
  1084. X        echo '#define VARARGS' >> args.h; \
  1085. X    else \
  1086. X        echo '#define SIMULATE_STDARG' >> args.h; \
  1087. X    fi
  1088. X    @echo 'args.h formed'
  1089. X
  1090. Xcalc.1: calc.man
  1091. X    rm -f calc.1
  1092. X    ${SED} -e 's:$${LIBDIR}:${LIBDIR}:g' < calc.man > calc.1
  1093. X
  1094. Xllib-lcalc.ln: ${BUILD_H_SRC} ${LIBSRC} Makefile
  1095. X    rm -f llib-lcalc.ln llib.out
  1096. X    -touch llib-lcalc.ln
  1097. X    ${LINTLIB} ${LIBSRC} 2>&1 | ${SED} -f lint.sed | ${TEE} llib.out
  1098. X
  1099. Xlint: ${BUILD_H_SRC} ${CALCSRC} llib-lcalc.ln lint.sed Makefile
  1100. X    rm -f lint.out
  1101. X    ${LINT} ${LINTFLAGS} ${LCFLAGS} llib-lcalc.ln ${CALCSRC} 2>&1 | \
  1102. X        ${SED} -f lint.sed | ${TEE} lint.out
  1103. X
  1104. Xtags: ${CALCSRC}
  1105. X    ${CTAGS} ${CALCSRC}
  1106. X
  1107. Xlintclean:
  1108. X    rm -f llib-lcalc.ln llib.out lint.out
  1109. X
  1110. Xclean:
  1111. X    rm -f ${LIBOBJS} ${CALCOBJS} ${CODEOBJS} endian.o
  1112. X    cd help; ${MAKE} -f Makefile LIBDIR=${LIBDIR} HELPDIR=${HELPDIR} clean
  1113. X
  1114. Xclobber: lintclean
  1115. X    rm -f ${LIBOBJS} ${CALCOBJS} ${CODEOBJS}
  1116. X    rm -f tags calc code libcalc.a
  1117. X    rm -f ${BUILD_H_SRC} calc.1 endian
  1118. X    cd help; ${MAKE} -f Makefile LIBDIR=${LIBDIR} HELPDIR=${HELPDIR} clobber
  1119. X
  1120. Xinstall: calc libcalc.a ${LIB_H_SRC} calc.1
  1121. X    -@if [ ! -d ${LIBDIR} ]; then \
  1122. X        echo ${MKDIR} ${LIBDIR}; \
  1123. X        ${MKDIR} ${LIBDIR}; \
  1124. X    fi
  1125. X    -chmod 0755 ${LIBDIR}
  1126. X    -@if [ ! -d ${HELPDIR} ]; then \
  1127. X        echo ${MKDIR} ${HELPDIR}; \
  1128. X        ${MKDIR} ${HELPDIR}; \
  1129. X    fi
  1130. X    -chmod 0755 ${HELPDIR}
  1131. X    -@if [ ! -d ${BINDIR} ]; then \
  1132. X        echo ${MKDIR} ${BINDIR}; \
  1133. X        ${MKDIR} ${BINDIR}; \
  1134. X    fi
  1135. X    -chmod 0755 ${BINDIR}
  1136. X    rm -f ${BINDIR}/calc
  1137. X    cp calc ${BINDIR}
  1138. X    -chmod 0555 ${BINDIR}/calc
  1139. X    cd help; ${MAKE} -f Makefile LIBDIR=${LIBDIR} HELPDIR=${HELPDIR} install
  1140. X    cd lib; ${MAKE} -f Makefile LIBDIR=${LIBDIR} install
  1141. X    rm -f ${LIBDIR}/libcalc.a
  1142. X    cp libcalc.a ${LIBDIR}/libcalc.a
  1143. X    -chmod 0644 ${LIBDIR}/libcalc.a
  1144. X    ${RANLIB} ${LIBDIR}/libcalc.a
  1145. X    @for i in ${LIB_H_SRC}; do \
  1146. X        echo rm -f ${LIBDIR}/$$i; \
  1147. X        rm -f ${LIBDIR}/$$i; \
  1148. X        echo cp $$i ${LIBDIR}; \
  1149. X        cp $$i ${LIBDIR}; \
  1150. X        echo chmod 0444 ${LIBDIR}/$$i; \
  1151. X        chmod 0444 ${LIBDIR}/$$i; \
  1152. X    done
  1153. X    @# If lint was made, install the lint library.
  1154. X    -@if [ -f llib-lcalc.ln ]; then \
  1155. X        echo rm -f ${LIBDIR}/llib-lcalc.ln; \
  1156. X        rm -f ${LIBDIR}/llib-lcalc.ln; \
  1157. X        echo cp llib-lcalc.ln ${LIBDIR}; \
  1158. X        cp llib-lcalc.ln ${LIBDIR}; \
  1159. X        echo chmod 0444 ${LIBDIR}/llib-lcalc.ln; \
  1160. X        chmod 0444 ${LIBDIR}/llib-lcalc.ln; \
  1161. X    fi
  1162. X    rm -f ${MANDIR}/calc.1
  1163. X    -cp calc.1 ${MANDIR}
  1164. X    -chmod 0444 ${MANDIR}/calc.1
  1165. X    @# The code program is not part of the calc distribution, don't worry
  1166. X    @# if you do not have it.
  1167. X    -@if [ -f code ]; then \
  1168. X        echo chmod +x code; \
  1169. X        chmod +x code; \
  1170. X        echo rm -f ${BINDIR}/code; \
  1171. X        rm -f ${BINDIR}/code; \
  1172. X        echo cp code ${BINDIR}; \
  1173. X        cp code ${BINDIR}; \
  1174. X        echo chmod 0555 ${BINDIR}/code; \
  1175. X        chmod 0555 ${BINDIR}/code; \
  1176. X    fi
  1177. X
  1178. X# The code program is not part of the calc distribution, don't worry
  1179. X# if you do not have it.
  1180. X#
  1181. Xcode: ${CODEOBJS} ${LIBOBJS}
  1182. X    ${CC} ${CFLAGS} ${CODEOBJS} libcalc.a -o code ${NO_SHARED}
  1183. X
  1184. Xcode.o:        code.c stdarg.h args.h qmath.h zmath.h alloc.h \
  1185. X        have_malloc.h have_string.h have_stdlib.h endian.h
  1186. X    ${CC} ${CFLAGS} code.c -c
  1187. X
  1188. X
  1189. X# make depend stuff
  1190. X#
  1191. Xaddop.o:    addop.c calc.h value.h cmath.h qmath.h zmath.h alloc.h \
  1192. X        have_malloc.h have_string.h have_stdlib.h opcodes.h string.h \
  1193. X        func.h label.h token.h symbol.h endian.h
  1194. Xalloc.o:    alloc.c alloc.h have_malloc.h have_string.h have_stdlib.h
  1195. Xassocfunc.o:    assocfunc.c value.h cmath.h qmath.h zmath.h alloc.h \
  1196. X        have_malloc.h have_string.h have_stdlib.h endian.h
  1197. Xcalc.o:        calc.c calc.h value.h cmath.h qmath.h zmath.h alloc.h \
  1198. X        have_malloc.h have_string.h have_stdlib.h hist.h func.h \
  1199. X        label.h opcodes.h config.h token.h symbol.h endian.h
  1200. Xcodegen.o:    codegen.c calc.h value.h cmath.h qmath.h zmath.h alloc.h \
  1201. X        have_malloc.h have_string.h have_stdlib.h token.h symbol.h \
  1202. X        label.h opcodes.h string.h func.h config.h endian.h
  1203. Xcomfunc.o:    comfunc.c cmath.h qmath.h zmath.h alloc.h have_malloc.h \
  1204. X        have_string.h have_stdlib.h endian.h
  1205. Xcommath.o:    commath.c cmath.h qmath.h zmath.h alloc.h have_malloc.h \
  1206. X        have_string.h have_stdlib.h endian.h
  1207. Xconfig.o:    config.c calc.h value.h cmath.h qmath.h zmath.h alloc.h \
  1208. X        have_malloc.h have_string.h have_stdlib.h endian.h
  1209. Xconst.o:    const.c calc.h value.h cmath.h qmath.h zmath.h alloc.h \
  1210. X        have_malloc.h have_string.h have_stdlib.h endian.h
  1211. Xfile.o:        file.c stdarg.h args.h calc.h value.h cmath.h qmath.h \
  1212. X        zmath.h alloc.h have_malloc.h have_string.h have_stdlib.h \
  1213. X        endian.h
  1214. Xfunc.o:        func.c calc.h value.h cmath.h qmath.h zmath.h alloc.h \
  1215. X        have_malloc.h have_string.h have_stdlib.h opcodes.h token.h \
  1216. X        func.h label.h string.h symbol.h endian.h
  1217. Xhist.o:        hist.c hist.h terminal.h
  1218. Xinput.o:    input.c calc.h value.h cmath.h qmath.h zmath.h alloc.h \
  1219. X        have_malloc.h have_string.h have_stdlib.h config.h hist.h \
  1220. X        endian.h
  1221. Xlabel.o:    label.c calc.h value.h cmath.h qmath.h zmath.h alloc.h \
  1222. X        have_malloc.h have_string.h have_stdlib.h token.h label.h \
  1223. X        string.h opcodes.h func.h endian.h
  1224. Xlistfunc.o:    listfunc.c value.h cmath.h qmath.h zmath.h alloc.h \
  1225. X        have_malloc.h have_string.h have_stdlib.h endian.h
  1226. Xmatfunc.o:    matfunc.c value.h cmath.h qmath.h zmath.h alloc.h \
  1227. X        have_malloc.h have_string.h have_stdlib.h endian.h
  1228. Xobj.o:        obj.c calc.h value.h cmath.h qmath.h zmath.h alloc.h \
  1229. X        have_malloc.h have_string.h have_stdlib.h opcodes.h func.h \
  1230. X        label.h symbol.h string.h endian.h
  1231. Xopcodes.o:    opcodes.c stdarg.h args.h calc.h value.h cmath.h qmath.h \
  1232. X        zmath.h alloc.h have_malloc.h have_string.h have_stdlib.h \
  1233. X        opcodes.h func.h label.h symbol.h hist.h endian.h
  1234. Xqfunc.o:    qfunc.c qmath.h zmath.h alloc.h have_malloc.h have_string.h \
  1235. X        have_stdlib.h endian.h
  1236. Xqio.o:        qio.c stdarg.h args.h qmath.h zmath.h alloc.h have_malloc.h \
  1237. X        have_string.h have_stdlib.h endian.h
  1238. Xqmath.o:    qmath.c qmath.h zmath.h alloc.h have_malloc.h have_string.h \
  1239. X        have_stdlib.h endian.h
  1240. Xqmod.o:        qmod.c qmath.h zmath.h alloc.h have_malloc.h have_string.h \
  1241. X        have_stdlib.h endian.h
  1242. Xqtrans.o:    qtrans.c qmath.h zmath.h alloc.h have_malloc.h have_string.h \
  1243. X        have_stdlib.h endian.h
  1244. Xstring.o:    string.c calc.h value.h cmath.h qmath.h zmath.h alloc.h \
  1245. X        have_malloc.h have_string.h have_stdlib.h string.h endian.h
  1246. Xsymbol.o:    symbol.c calc.h value.h cmath.h qmath.h zmath.h alloc.h \
  1247. X        have_malloc.h have_string.h have_stdlib.h token.h symbol.h \
  1248. X        string.h opcodes.h func.h label.h endian.h
  1249. Xtoken.o:    token.c stdarg.h args.h calc.h value.h cmath.h qmath.h \
  1250. X        zmath.h alloc.h have_malloc.h have_string.h have_stdlib.h \
  1251. X        token.h string.h endian.h
  1252. Xvalue.o:    value.c value.h cmath.h qmath.h zmath.h alloc.h \
  1253. X        have_malloc.h have_string.h have_stdlib.h opcodes.h func.h \
  1254. X        calc.h label.h symbol.h string.h endian.h
  1255. Xversion.o:    version.c calc.h value.h cmath.h qmath.h zmath.h alloc.h \
  1256. X        have_malloc.h have_string.h have_stdlib.h endian.h
  1257. Xzfunc.o:    zfunc.c zmath.h alloc.h have_malloc.h have_string.h \
  1258. X        have_stdlib.h endian.h
  1259. Xzio.o:        zio.c stdarg.h args.h zmath.h alloc.h have_malloc.h \
  1260. X        have_string.h have_stdlib.h endian.h
  1261. Xzmath.o:    zmath.c zmath.h alloc.h have_malloc.h have_string.h \
  1262. X        have_stdlib.h endian.h
  1263. Xzmod.o:        zmod.c zmath.h alloc.h have_malloc.h have_string.h \
  1264. X        have_stdlib.h endian.h
  1265. Xzmul.o:        zmul.c zmath.h alloc.h have_malloc.h have_string.h \
  1266. X        have_stdlib.h endian.h
  1267. SHAR_EOF
  1268. chmod 0644 calc2.9.0/Makefile || echo "restore of calc2.9.0/Makefile fails"
  1269. set `wc -c calc2.9.0/Makefile`;Sum=$1
  1270. if test "$Sum" != "20426"
  1271. then echo original size 20426, current size $Sum;fi
  1272. echo "x - extracting calc2.9.0/addop.c (Text)"
  1273. sed 's/^X//' << 'SHAR_EOF' > calc2.9.0/addop.c &&
  1274. X/*
  1275. X * Copyright (c) 1993 David I. Bell
  1276. X * Permission is granted to use, distribute, or modify this source,
  1277. X * provided that this copyright notice remains intact.
  1278. X *
  1279. X * Add opcodes to a function being compiled.
  1280. X */
  1281. X
  1282. X#include "calc.h"
  1283. X#include "opcodes.h"
  1284. X#include "string.h"
  1285. X#include "func.h"
  1286. X#include "token.h"
  1287. X#include "label.h"
  1288. X#include "symbol.h"
  1289. X
  1290. X
  1291. X#define    FUNCALLOCSIZE    20    /* reallocate size for functions */
  1292. X#define    OPCODEALLOCSIZE    100    /* reallocate size for opcodes in functions */
  1293. X
  1294. X
  1295. Xstatic long maxopcodes;        /* number of opcodes available */
  1296. Xstatic long newindex;        /* index of new function */
  1297. Xstatic long oldop;        /* previous opcode */
  1298. Xstatic long debugline;        /* line number of latest debug opcode */
  1299. Xstatic long funccount;        /* number of functions */
  1300. Xstatic long funcavail;        /* available number of functions */
  1301. Xstatic FUNC *functemplate;    /* function definition template */
  1302. Xstatic FUNC **functions;    /* table of functions */
  1303. Xstatic STRINGHEAD funcnames;    /* function names */
  1304. Xstatic int codeflag;
  1305. X
  1306. X
  1307. X/*
  1308. X * Initialize the table of user defined functions.
  1309. X */
  1310. Xvoid
  1311. Xinitfunctions()
  1312. X{
  1313. X    initstr(&funcnames);
  1314. X    maxopcodes = OPCODEALLOCSIZE;
  1315. X    functemplate = (FUNC *) malloc(funcsize(maxopcodes));
  1316. X    if (functemplate == NULL)
  1317. X        math_error("Cannot allocate function template");
  1318. X    functions = (FUNC **) malloc(sizeof(FUNC *) * FUNCALLOCSIZE);
  1319. X    if (functions == NULL)
  1320. X        math_error("Cannot allocate function table");
  1321. X    funccount = 0;
  1322. X    funcavail = FUNCALLOCSIZE;
  1323. X}
  1324. X
  1325. X
  1326. X/*
  1327. X * Show the list of user defined functions.
  1328. X */
  1329. Xvoid
  1330. Xshowfunctions()
  1331. X{
  1332. X    FUNC **fpp;        /* pointer into function table */
  1333. X    FUNC *fp;        /* current function */
  1334. X
  1335. X    if (funccount == 0) {
  1336. X        printf("No user functions defined.\n");
  1337. X        return;
  1338. X    }
  1339. X    printf("Name Arguments\n");
  1340. X    printf("---- ---------\n");
  1341. X    for (fpp = &functions[funccount - 1]; fpp >= functions; fpp--) {
  1342. X        fp = *fpp;
  1343. X        if (fp == NULL)
  1344. X            continue;
  1345. X        printf("%-12s %-2d\n", fp->f_name, fp->f_paramcount);
  1346. X    }
  1347. X    printf("\n");
  1348. X}
  1349. X
  1350. X
  1351. X/*
  1352. X * Initialize a function for definition.
  1353. X * Newflag is TRUE if we should allocate a new function structure,
  1354. X * instead of the usual overwriting of the template function structure.
  1355. X * The new structure is returned in the global curfunc variable.
  1356. X */
  1357. Xvoid
  1358. Xbeginfunc(name, newflag)
  1359. X    char *name;            /* name of function */
  1360. X    BOOL newflag;            /* TRUE if need new structure */
  1361. X{
  1362. X    register FUNC *fp;        /* current function */
  1363. X
  1364. X    newindex = adduserfunc(name);
  1365. X    maxopcodes = OPCODEALLOCSIZE;
  1366. X    fp = functemplate;
  1367. X    if (newflag) {
  1368. X        fp = (FUNC *) malloc(funcsize(maxopcodes));
  1369. X        if (fp == NULL)
  1370. X            math_error("Cannot allocate temporary function");
  1371. X    }
  1372. X    fp->f_next = NULL;
  1373. X    fp->f_localcount = 0;
  1374. X    fp->f_opcodecount = 0;
  1375. X    fp->f_savedvalue.v_type = V_NULL;
  1376. X    fp->f_name = namestr(&funcnames, newindex);
  1377. X    curfunc = fp;
  1378. X    initlocals();
  1379. X    initlabels();
  1380. X    oldop = OP_NOP;
  1381. X    debugline = 0;
  1382. X    errorcount = 0;
  1383. X}
  1384. X
  1385. X
  1386. X/*
  1387. X * Commit the just defined function for use.
  1388. X * This replaces any existing definition for the function.
  1389. X * This should only be called for normal user-defined functions.
  1390. X */
  1391. Xvoid
  1392. Xendfunc()
  1393. X{
  1394. X    register FUNC *fp;        /* function just finished */
  1395. X    long size;            /* size of just created function */
  1396. X
  1397. X    checklabels();
  1398. X    if (errorcount) {
  1399. X        printf("\"%s\": %ld error%s\n", curfunc->f_name, errorcount,
  1400. X            ((errorcount == 1) ? "" : "s"));
  1401. X        return;
  1402. X    }
  1403. X    size = funcsize(curfunc->f_opcodecount);
  1404. X    fp = (FUNC *) malloc(size);
  1405. X    if (fp == NULL)
  1406. X        math_error("Cannot commit function");
  1407. X    memcpy((char *) fp, (char *) curfunc, size);
  1408. X    if (curfunc != functemplate)
  1409. X        free(curfunc);
  1410. X    if (codeflag) {
  1411. X        for (size = 0; size < fp->f_opcodecount; ) {
  1412. X            printf("%ld: ", (long)size);
  1413. X            size += dumpop(&fp->f_opcodes[size]);
  1414. X        }
  1415. X    }
  1416. X    if (functions[newindex])
  1417. X        free(functions[newindex]);
  1418. X    functions[newindex] = fp;
  1419. X    objuncache();
  1420. X    if (inputisterminal())
  1421. X        printf("\"%s\" defined\n", fp->f_name);
  1422. X}
  1423. X
  1424. X
  1425. X/*
  1426. X * Find the user function with the specified name, and return its index.
  1427. X * If the function does not exist, its name is added to the function table
  1428. X * and an error will be generated when it is called if it is still undefined.
  1429. X */
  1430. Xlong
  1431. Xadduserfunc(name)
  1432. X    char *name;        /* name of function */
  1433. X{
  1434. X    long index;        /* index of function */
  1435. X
  1436. X    index = findstr(&funcnames, name);
  1437. X    if (index >= 0)
  1438. X        return index;
  1439. X    if (funccount >= funcavail) {
  1440. X        functions = (FUNC **) realloc(functions,
  1441. X            sizeof(FUNC *) * (funcavail + FUNCALLOCSIZE));
  1442. X        if (functions == NULL)
  1443. X            math_error("Failed to reallocate function table");
  1444. X        funcavail += FUNCALLOCSIZE;
  1445. X    }
  1446. X    if (addstr(&funcnames, name) == NULL)
  1447. X        math_error("Cannot save function name");
  1448. X    index = funccount++;
  1449. X    functions[index] = NULL;
  1450. X    return index;
  1451. X}
  1452. X
  1453. X
  1454. X/*
  1455. X * Clear any optimization that may be done for the next opcode.
  1456. X * This is used when defining a label.
  1457. X */
  1458. Xvoid
  1459. Xclearopt()
  1460. X{
  1461. X    oldop = OP_NOP;
  1462. X    debugline = 0;
  1463. X}
  1464. X
  1465. X
  1466. X/*
  1467. X * Find a function structure given its index.
  1468. X */
  1469. XFUNC *
  1470. Xfindfunc(index)
  1471. X    long index;
  1472. X{
  1473. X    if ((unsigned long) index >= funccount)
  1474. X        math_error("Undefined function");
  1475. X    return functions[index];
  1476. X}
  1477. X
  1478. X
  1479. X/*
  1480. X * Return the name of a function given its index.
  1481. X */
  1482. Xchar *
  1483. Xnamefunc(index)
  1484. X    long index;
  1485. X{
  1486. X    return namestr(&funcnames, index);
  1487. X}
  1488. X
  1489. X
  1490. X/*
  1491. X * Let a matrix indexing operation know that it will be treated as a write
  1492. X * reference instead of just as a read reference.
  1493. X */
  1494. Xvoid
  1495. Xwriteindexop()
  1496. X{
  1497. X    if (oldop == OP_INDEXADDR)
  1498. X        curfunc->f_opcodes[curfunc->f_opcodecount - 1] = TRUE;
  1499. X}
  1500. X
  1501. X
  1502. X/*
  1503. X * Add an opcode to the current function being compiled.
  1504. X * Note: This can change the curfunc global variable when the
  1505. X * function needs expanding.
  1506. X */
  1507. Xvoid
  1508. Xaddop(op)
  1509. X    long op;
  1510. X{
  1511. X    register FUNC *fp;        /* current function */
  1512. X    NUMBER *q;
  1513. X
  1514. X    fp = curfunc;
  1515. X    if ((fp->f_opcodecount + 5) >= maxopcodes) {
  1516. X        maxopcodes += OPCODEALLOCSIZE;
  1517. X        fp = (FUNC *) malloc(funcsize(maxopcodes));
  1518. X        if (fp == NULL)
  1519. X            math_error("cannot reallocate function");
  1520. X        memcpy((char *) fp, (char *) curfunc,
  1521. X            funcsize(curfunc->f_opcodecount));
  1522. X        if (curfunc != functemplate)
  1523. X            free(curfunc);
  1524. X        curfunc = fp;
  1525. X    }
  1526. X    /*
  1527. X     * Check the current opcode against the previous opcode and try to
  1528. X     * slightly optimize the code depending on the various combinations.
  1529. X     */
  1530. X    if (op == OP_GETVALUE) {
  1531. X        switch (oldop) {
  1532. X
  1533. X        case OP_NUMBER: case OP_ZERO: case OP_ONE: case OP_IMAGINARY:
  1534. X        case OP_GETEPSILON: case OP_SETEPSILON: case OP_STRING:
  1535. X        case OP_UNDEF: case OP_GETCONFIG: case OP_SETCONFIG:
  1536. X            return;
  1537. X        case OP_DUPLICATE:
  1538. X            fp->f_opcodes[fp->f_opcodecount - 1] = OP_DUPVALUE;
  1539. X            oldop = OP_DUPVALUE;
  1540. X            return;
  1541. X        case OP_FIADDR:
  1542. X            fp->f_opcodes[fp->f_opcodecount - 1] = OP_FIVALUE;
  1543. X            oldop = OP_FIVALUE;
  1544. X            return;
  1545. X        case OP_GLOBALADDR:
  1546. X            fp->f_opcodes[fp->f_opcodecount - 2] = OP_GLOBALVALUE;
  1547. X            oldop = OP_GLOBALVALUE;
  1548. X            return;
  1549. X        case OP_LOCALADDR:
  1550. X            fp->f_opcodes[fp->f_opcodecount - 2] = OP_LOCALVALUE;
  1551. X            oldop = OP_LOCALVALUE;
  1552. X            return;
  1553. X        case OP_PARAMADDR:
  1554. X            fp->f_opcodes[fp->f_opcodecount - 2] = OP_PARAMVALUE;
  1555. X            oldop = OP_PARAMVALUE;
  1556. X            return;
  1557. X        case OP_ELEMADDR:
  1558. X            fp->f_opcodes[fp->f_opcodecount - 2] = OP_ELEMVALUE;
  1559. X            oldop = OP_ELEMVALUE;
  1560. X            return;
  1561. X        }
  1562. X    }
  1563. X    if ((op == OP_NEGATE) && (oldop == OP_NUMBER)) {
  1564. X        q = constvalue(fp->f_opcodes[fp->f_opcodecount - 1]);
  1565. X        fp->f_opcodes[fp->f_opcodecount - 1] = addqconstant(qneg(q));
  1566. X        oldop = OP_NUMBER;
  1567. X        return;
  1568. X    }
  1569. X    if ((op == OP_POWER) && (oldop == OP_NUMBER)) {
  1570. X        if (qcmpi(constvalue(fp->f_opcodes[fp->f_opcodecount - 1]), 2L) == 0) {
  1571. X            fp->f_opcodecount--;
  1572. X            fp->f_opcodes[fp->f_opcodecount - 1] = OP_SQUARE;
  1573. X            oldop = OP_SQUARE;
  1574. X            return;
  1575. X        }
  1576. X        if (qcmpi(constvalue(fp->f_opcodes[fp->f_opcodecount - 1]), 4L) == 0) {
  1577. X            fp->f_opcodes[fp->f_opcodecount - 2] = OP_SQUARE;
  1578. X            fp->f_opcodes[fp->f_opcodecount - 1] = OP_SQUARE;
  1579. X            oldop = OP_SQUARE;
  1580. X            return;
  1581. X        }
  1582. X    }
  1583. X    if ((op == OP_POP) && (oldop == OP_ASSIGN)) {    /* optimize */
  1584. X        fp->f_opcodes[fp->f_opcodecount - 1] = OP_ASSIGNPOP;
  1585. X        oldop = OP_ASSIGNPOP;
  1586. X        return;
  1587. X    }
  1588. X    /*
  1589. X     * No optimization possible, so store the opcode.
  1590. X     */
  1591. X    fp->f_opcodes[fp->f_opcodecount] = op;
  1592. X    fp->f_opcodecount++;
  1593. X    oldop = op;
  1594. X}
  1595. X
  1596. X
  1597. X/*
  1598. X * Add an opcode and and one integer argument to the current function
  1599. X * being compiled.
  1600. X */
  1601. Xvoid
  1602. Xaddopone(op, arg)
  1603. X    long op;
  1604. X    long arg;
  1605. X{
  1606. X    NUMBER *q;
  1607. X
  1608. X    switch (op) {
  1609. X    case OP_NUMBER:
  1610. X        q = constvalue(arg);
  1611. X        if (q == NULL)
  1612. X            break;
  1613. X        if (qiszero(q)) {
  1614. X            addop(OP_ZERO);
  1615. X            return;
  1616. X        }
  1617. X        if (qisone(q)) {
  1618. X            addop(OP_ONE);
  1619. X            return;
  1620. X        }
  1621. X        break;
  1622. X
  1623. X    case OP_DEBUG:
  1624. X        if ((traceflags & TRACE_NODEBUG) || (arg == debugline))
  1625. X            return;
  1626. X        debugline = arg;
  1627. X        if (oldop == OP_DEBUG) {
  1628. X            curfunc->f_opcodes[curfunc->f_opcodecount - 1] = arg;
  1629. X            return;
  1630. X        }
  1631. X        break;
  1632. X    }
  1633. X    addop(op);
  1634. X    curfunc->f_opcodes[curfunc->f_opcodecount] = arg;
  1635. X    curfunc->f_opcodecount++;
  1636. X}
  1637. X
  1638. X
  1639. X/*
  1640. X * Add an opcode and and two integer arguments to the current function
  1641. X * being compiled.
  1642. X */
  1643. Xvoid
  1644. Xaddoptwo(op, arg1, arg2)
  1645. X    long op;
  1646. X    long arg1;
  1647. X    long arg2;
  1648. X{
  1649. X    addop(op);
  1650. X    curfunc->f_opcodes[curfunc->f_opcodecount++] = arg1;
  1651. X    curfunc->f_opcodes[curfunc->f_opcodecount++] = arg2;
  1652. X}
  1653. X
  1654. X
  1655. X/*
  1656. X * Add an opcode and a character pointer to the function being compiled.
  1657. X */
  1658. Xvoid
  1659. Xaddopptr(op, ptr)
  1660. X    long op;
  1661. X    char *ptr;
  1662. X{
  1663. X    char **ptraddr;
  1664. X
  1665. X    addop(op);
  1666. X    ptraddr = (char **) &curfunc->f_opcodes[curfunc->f_opcodecount];
  1667. X    *ptraddr = ptr;
  1668. X    curfunc->f_opcodecount += PTR_SIZE;
  1669. X}
  1670. X
  1671. X
  1672. X/*
  1673. X * Add an opcode and an index and an argument count for a function call.
  1674. X */
  1675. Xvoid
  1676. Xaddopfunction(op, index, count)
  1677. X    long op;
  1678. X    long index;
  1679. X{
  1680. X    long newop;
  1681. X
  1682. X    if ((op == OP_CALL) && ((newop = builtinopcode(index)) != OP_NOP)) {
  1683. X        if ((newop == OP_SETCONFIG) && (count == 1))
  1684. X            newop = OP_GETCONFIG;
  1685. X        if ((newop == OP_SETEPSILON) && (count == 0))
  1686. X            newop = OP_GETEPSILON;
  1687. X        if ((newop == OP_ABS) && (count == 1))
  1688. X            addop(OP_GETEPSILON);
  1689. X        addop(newop);
  1690. X        return;
  1691. X    }
  1692. X    addop(op);
  1693. X    curfunc->f_opcodes[curfunc->f_opcodecount++] = index;
  1694. X    curfunc->f_opcodes[curfunc->f_opcodecount++] = count;
  1695. X}
  1696. X
  1697. X
  1698. X/*
  1699. X * Add a jump-type opcode and a label to the function being compiled.
  1700. X */
  1701. Xvoid
  1702. Xaddoplabel(op, label)
  1703. X    long op;
  1704. X    LABEL *label;        /* label to be added */
  1705. X{
  1706. X    addop(op);
  1707. X    uselabel(label);
  1708. X}
  1709. X
  1710. X/* END CODE */
  1711. SHAR_EOF
  1712. chmod 0644 calc2.9.0/addop.c || echo "restore of calc2.9.0/addop.c fails"
  1713. set `wc -c calc2.9.0/addop.c`;Sum=$1
  1714. if test "$Sum" != "9951"
  1715. then echo original size 9951, current size $Sum;fi
  1716. echo "x - extracting calc2.9.0/alloc.c (Text)"
  1717. sed 's/^X//' << 'SHAR_EOF' > calc2.9.0/alloc.c &&
  1718. X/*
  1719. X * Copyright (c) 1993 David I. Bell
  1720. X * Permission is granted to use, distribute, or modify this source,
  1721. X * provided that this copyright notice remains intact.
  1722. X *
  1723. X * Description:
  1724. X *    This is a very fast storage allocator. It allocates blocks of a small
  1725. X *    number of different sizes, and keeps free lists of each size.  Blocks
  1726. X *    that don't exactly fit are passed up to the next larger size.  In this
  1727. X *    implementation, the available sizes are 2^n-4 (or 2^n-12) bytes long.
  1728. X *    This is designed for use in a program that uses vast quantities of
  1729. X *    memory, but bombs when it runs out.
  1730. X *
  1731. X * Abnormal Conditions
  1732. X *    This is a public domain storage allocator.
  1733. X *
  1734. X * Modifications:
  1735. X *    Date        Programmer        Description of modification
  1736. X *    27-FEB-90    Landon Curt Noll    most systems can ignore alloc.c
  1737. X *    2-OCT-89    David I. Bell        Add free list. Sbrk now optional
  1738. X *    30-JUN-87    Peter Miller        Made it work on Slimos.
  1739. X *    21-FEB-82    Chris Kingsley        Initial Coding
  1740. X *            kingsley@cit-20        Caltech
  1741. X */
  1742. X
  1743. X#include <stdio.h>
  1744. X#include "alloc.h"
  1745. X#include "have_stdlib.h"
  1746. X
  1747. X#if 0
  1748. X#define DEBUG    1        /* defined if debugging code enabled */
  1749. X#define MSTATS    1        /* defined if memory statistics kept */
  1750. X#endif
  1751. X#define    NO_SBRK    1        /* defined if cannot use sbrk */
  1752. X
  1753. X
  1754. X#if defined(CALC_MALLOC)
  1755. X/*
  1756. X * Make these functions really accessible here.
  1757. X */
  1758. X#undef    malloc
  1759. X#undef    realloc
  1760. X#undef    free
  1761. X
  1762. X
  1763. X#ifdef DEBUG
  1764. X#define assert(x,v) if ((x)==0) assertfailed(v)
  1765. X#else
  1766. X#define assert(x,v)
  1767. X#endif
  1768. X
  1769. Xtypedef unsigned char u_char;
  1770. Xtypedef unsigned short u_short;
  1771. Xtypedef unsigned int u_int;
  1772. Xtypedef char * caddr_t;
  1773. X
  1774. X#ifdef NO_SBRK
  1775. Xextern char * malloc();
  1776. Xextern char * realloc();
  1777. X#else
  1778. Xextern char * sbrk();
  1779. X#endif
  1780. X
  1781. X
  1782. X/*
  1783. X * The overhead on a block is at least 4 bytes.  When free, this space
  1784. X * contains a pointer to the next free block, and the bottom two bits must
  1785. X * be zero.  When in use, the first byte is set to MAGIC, and the second
  1786. X * byte is the size index.  The remaining bytes are for alignment.
  1787. X * If range checking (RCHECK) is enabled and the size of the block fits
  1788. X * in two bytes, then the top two bytes hold the size of the requested block
  1789. X * plus the range checking words, and the header word MINUS ONE.
  1790. X */
  1791. X
  1792. Xunion overhead
  1793. X{
  1794. X    union overhead * ov_next;    /* when free */
  1795. X    struct
  1796. X    {
  1797. X        u_char ovu_magic;    /* magic number */
  1798. X        u_char ovu_index;    /* bucket # */
  1799. X#define ov_magic ovu.ovu_magic
  1800. X#define ov_index ovu.ovu_index
  1801. X#ifdef RCHECK
  1802. X        u_short ovu_size;    /* actual block size */
  1803. X        u_int ovu_rmagic;    /* range magic number */
  1804. X#define ov_size ovu.ovu_size
  1805. X#define ov_rmagic ovu.ovu_rmagic
  1806. X#endif
  1807. X    } ovu;
  1808. X};
  1809. X
  1810. X#define QUANTUM_NBITS    4
  1811. X#define QUANTUM        (1<<QUANTUM_NBITS)
  1812. X
  1813. X#define MAGIC    0xff        /* magic # on accounting info */
  1814. X#define RMAGIC    0x55555555    /* magic # on range info */
  1815. X#ifdef RCHECK
  1816. X#define RSLOP    sizeof(u_int)
  1817. X#else
  1818. X#define RSLOP    0
  1819. X#endif
  1820. X
  1821. X/*
  1822. X * nextf[i] is the pointer to the next free block of size 2^(i+3).  The
  1823. X * smallest allocatable block is 8 bytes.  The overhead information
  1824. X * precedes the data area returned to the user.
  1825. X */
  1826. X
  1827. X#define NBUCKETS    32    /* we can't run out on a 32 bit machine! */
  1828. Xstatic union overhead * nextf[NBUCKETS];
  1829. Xstatic union overhead *watchloc = 0;    /* location to be watched */
  1830. X
  1831. X#ifdef MSTATS
  1832. X
  1833. X/*
  1834. X * nmalloc[i] is the difference between the number of mallocs and frees
  1835. X * for a given block size.
  1836. X */
  1837. X
  1838. Xstatic u_int nmalloc[NBUCKETS];
  1839. X
  1840. X#endif
  1841. X
  1842. X
  1843. X/*
  1844. X * Watch some allocated memory to see if it gets blasted.
  1845. X */
  1846. Xallocwatch(cp)
  1847. X    char *cp;
  1848. X{
  1849. X    if (cp == NULL) {
  1850. X        watchloc = NULL;
  1851. X        return;
  1852. X    }
  1853. X    watchloc = (union overhead *)cp - 1;
  1854. X    assert(watchloc->ov_magic == MAGIC, 10);
  1855. X}
  1856. X
  1857. X
  1858. Xalloccheck()
  1859. X{
  1860. X    assert((watchloc == NULL) || (watchloc->ov_magic == MAGIC), 11);
  1861. X}
  1862. X
  1863. X
  1864. X/*
  1865. X * NAME
  1866. X *    morecore - get more memory
  1867. X *
  1868. X * SYNOPSIS
  1869. X *    void
  1870. X *    morecore(bucket)
  1871. X *    int bucket;
  1872. X *
  1873. X * DESCRIPTION
  1874. X *    Morecore is used to allocate more memory to the indicated bucket.
  1875. X *
  1876. X * RETURNS
  1877. X *    void
  1878. X */
  1879. Xstatic void
  1880. Xmorecore(bucket)
  1881. X    register u_int    bucket;
  1882. X{
  1883. X    register union overhead * op;
  1884. X    register u_int    rnu;    /* 2^rnu bytes will be requested */
  1885. X    register u_int    nblks;    /* become nblks blocks of the desired size */
  1886. X    register u_int    siz;
  1887. SHAR_EOF
  1888. echo "End of part 1"
  1889. echo "File calc2.9.0/alloc.c is continued in part 2"
  1890. echo "2" > s2_seq_.tmp
  1891. exit 0
  1892.