rsalz@bbn.com (Rich Salz) (12/19/90)
Submitted-by: Steven Pemberton <steven@cwi.nl> Posting-number: Volume 23, Issue 89 Archive-name: abc/part10 #! /bin/sh # This is a shell archive. Remove anything before this line, then feed it # into a shell via "sh file" or similar. To overwrite existing files, # type "sh file -c". # The tool that generated this appeared in the comp.sources.unix newsgroup; # send mail to comp-sources-unix@uunet.uu.net if you want that tool. # Contents: abc/abc.msg abc/bed/e1edoc.c abc/bint1/i1fun.c # abc/ch_config # Wrapped by rsalz@litchi.bbn.com on Mon Dec 17 13:28:01 1990 PATH=/bin:/usr/bin:/usr/ucb ; export PATH echo If this archive is complete, you will see the following message: echo ' "shar: End of archive 10 (of 25)."' if test -f 'abc/abc.msg' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'abc/abc.msg'\" else echo shar: Extracting \"'abc/abc.msg'\" \(18006 characters\) sed "s/^X//" >'abc/abc.msg' <<'END_OF_FILE' X100 removing non-existent list entry X101 cannot remove from large range X102 cannot insert in large range X103 in keys t, t is not a table X104 in t[k], t is not a table X105 in t[k], k is not a key of t X106* comp_text (106) X200 in t|n, t is not a text X201 in t|n, n is not a number X202 in t|n, n is not an integer X203 in t|n, n is < 0 X204 in t@n, t is not a text X205 in t@n, n is not a number X206 in t@n, n is not an integer X207 in t@n, n is > #t + 1 X208 in t^u, t or u is not a text X209 in t^u, the result is too long X210 in t^^n, t is not a text X211 in t^^n, n is not a number X212 in t^^n, n is not an integer X213 in t^^n, n is negative X214 in t^^n, the result is too long X215* charval on non-char (215) X216* strval on big text (216) X217* curtail on very big text (217) X218* behead on very big text (218) X219* concat on very big text (219) X300 in #t, t is not a text list or table X301 in e#t, t is not a text list or table X302 in e#t, t is a text, but e is not a character X303 in min t, t is not a text list or table X304 in min t, t is empty X305 in max t, t is not a text list or table X306 in max t, t is empty X307 in e min t, t is not a text list or table X308 in e min t, t is empty X309 in e min t, t is a text, but e is not a character X310 in e min t, no element of t exceeds e X311 in e max t, t is not a text list or table X312 in e max t, t is empty X313 in e max t, t is a text, but e is not a character X314 in e max t, no element of t is less than e X315 in t item n, t is not a text list or table X316 in t item n, t is empty X317 in t item n, n is not a number X318 in t item n, n is not an integer X319 in t item n, n is < 1 X320 in t item n, n exceeds #t X321 in n th'of t, t is not a text list or table X322 in n th'of t, t is empty X323 in n th'of t, n is not a number X324 in n th'of t, n is not an integer X325 in n th'of t, n is < 1 X326 in n th'of t, n exceeds #t X327* Bigsize in Bottom or Crange (327) X400* unknown flag in ccopybtreenode (400) X401* releasing unreferenced btreenode (401) X402* wrong flag in relbtree() (402) X500 incompatible types %s and %s X501* comparison of unknown types (501) X502* hash called with unknown type (502) X503* unknown type in convert (503) X600 in x mod y, y is zero X601 in n round x, n is not an integer X602 in */n, n is an approximate number X603 in /*n, n is an approximate number X604 in n root x, n is zero X605 in root x, x is negative X606 result of math function too large X607 argument to math function too large X608 math library error X609 in log x, x <= 0 X610 in b log x, b <= 0 X611 in b log x, x <= 0 X700 approximate number too large X701* app_floor: result not integral (701) X800* numconst: can't happen (800) X801 excessive exponent in e-notation X900* dig_gcd of number(s) <= 0 (900) X901* gcd_small of numbers > smallint (901) X902* gcd of number(s) <= 0 (902) X903 exceptionally large rational number X1000* dig_gadd: nto < nfrom (1000) X1001* int_tento(-n) (1001) X1100* zero division (int_ldiv) (1100) X1101* int_ldiv internal failure (1101) X1200* mk_rat(x, y) with y=0 (1200) X1300 number not an integer X1301 exceedingly large integer X1302* intval on non-number (1302) X1303* num_comp (1303) X1304 value not a number X1305 approximate number too large to be handled X1306 exceptionally large number X1400 in p..q, p is neither a text nor a number X1401 in p..q, p is a number but not an integer X1402 in p..q, p is a number, but q is not X1403 in p..q, q is a number but not an integer X1404 in p..q, p is a text but not a character X1405 in p..q, p is a text, but q is not X1406 in p..q, q is a text, but not a character X1500* big grabber (1500) X1501* big regrabber (1501) X1502* getsyze called with unknown type (1502) X1503* releasing unreferenced value (1503) X1600 in choice t, t is not a text list or table X1601 in choice t, t is empty X1700 Type '?' for help.\n X1800 in i/j, j is zero X1801 in 0**y or y root 0, y is negative X1802 in x**(p/q) or (q/p) root x, x is negative and q is even X1803 in x**y or y root x, x is negative and y is not exact X1804 ambiguous expression; please use ( and ) to resolve X1805 no expression where expected X1806 no test where expected X1807 something unexpected in expression X1808 something unexpected in test X1809 misformed address X1810 %s hasn't been initialised or (properly) defined X1811 %s hasn't been (properly) defined X1812 %s has not yet received a value X1813 function returns no value X1814 predicate reports no outcome X1815 a refinement may not be used as an address X1816 bad node in while X1817 bad node in testsuite X1818 indentation not used consistently X1819 indentation must be at least 2 X1820 selection on non-table X1900* a_fpr_formals (1900) X1901* analyze bad tree (1901) X2000 no command suite where expected X2001 no command where expected X2002 something unexpected in this line X2003 no parameter where expected X2005 IN after colon X2006 no alternative suite for SELECT X2007 after ELSE no more alternatives allowed X2100 nothing instead of expected expression X2101 point without digits X2102 e not followed by exponent X2103 cannot find matching %s X2200* fix bad tree (2200) X2201* fix unparsed with bad flag (2201) X2202 command cannot be reached X2203 refinement returns no value or reports no outcome X2204 wrong keyword %s X2205 missing actual parameter after %s X2206 can't find expected %s X2207 unexpected actual parameter after %s X2208 unexpected keyword %s X2209 compound parameter has wrong length X2210 refinement with parameters X2211 you haven't told me HOW TO %s X2212* f_fpr_formals (2212) X2213 %s cannot be used in an expression X2214 %s is neither a refined test nor a zeroadic predicate X2300 wrong argument of type_check() X2301 next line must be impossible as a refinement name, e.g. with a space: X2302 returned value X2303 RETURN not in function or expression refinement X2304 Empty polytype stack X2400 cannot find expected %s X2401 no name where expected X2402 no keyword where expected X2403 something unexpected following %s X2404 according to the syntax I expected %s X2500 nothing where address expected X2501 no address where expected X2502 something unexpected in address X2600 I found type X2601 EG X2602 where I expected X2603 I thought X2604 was of type X2605 list or table of X2606 list or table X2607 "", or list or table of "" X2608 text or list or table X2609 incompatible type for X2610 incompatible types for X2611 and X2612 %s X2700 HAS follows colon X2701 nothing instead of expected test X2800 how-to starts with indentation X2801 no how-to name where expected X2802 no how-to keyword where expected X2803 %s is a reserved keyword X2804 %s is already a formal parameter or operand X2805 %s is already a shared name X2806 %s is already a refinement name X2807 cannot find function name X2808 user defined functions must be names X2809 something unexpected in formula template X2810 nothing instead of expected template operand X2811 no template operand where expected X2812 nothing instead of expected name X2813 no name where expected X2814 something unexpected in name X2900 change of workspace not allowed X2901 no previous workspace X2902 I find no workspace name here X2903 I can't goto/create workspace %s X2905 *** I cannot find parent directory\n X2906 *** I cannot find workspace\n X2907 *** I cannot find your home directory\n X2908 *** I shall use the current directory as your single workspace\n X2909 *** %s isn't an ABC name\n X2910 *** I shall try the default workspace\n X3000* replacing in non-environment (3000) X3001* deleting from non-environment (3001) X3002* selection on non-environment (3002) X3100 in your command\n X3101 in your expression to be read\n X3102 in your edited value\n X3103 in your location %s\n X3104 in your permanent environment\n X3105 in your workspace index\n X3106 in your how-to %s\n X3107 in line %d of your how-to %s\n X3108 *** (detected after reading 1 line of your input file standard input)\n X3109 *** (detected after reading %d lines of your input file standard input)\n X3110 *** (detected after reading 1 line of your input file %s)\n X3111 *** (detected after reading %d lines of your input file %s)\n X3112 *** The problem is: X3113 *** Sorry, ABC system malfunction\n X3114 *** Sorry, memory exhausted X3115 *** There's something I don't understand X3116 *** There's something I can't resolve X3117 *** Can't cope with problem X3118 *** Cannot reconcile the types X3119 *** Your check failed X3120 *** interrupted\n X3200 in x %s y, x is not a number X3201 in x %s y, y is not a number X3202 in x %s y, y is not a compound of two numbers X3203 in c %s x, c is zero X3204 in %s x, x is not a number X3205 in %s y, y is not a compound of two numbers X3206 in %s t, t is not a text X3207* pre-defined fpr wrong (3207) X3208 in the test exact x, x is not a number X3209 in the test e in t, t is not a text list or table X3210 in the test e in t, t is a text, but e is not a character X3211 in the test e not.in t, t is not a text list or table X3212 in the test e not.in t, t is a text, but e isn't a character X3213* predicate not covered by proposition (3213) X3300 terminating commands only allowed in how-to's and refinements X3301 share-command only allowed in a how-to X3302 I don't recognise this as a command X3303 outer indentation not zero X3304 special commands only interactively X3305* special (3305) X3400 in ... i IN e, e is not a text, list or table X3500 unexpected program halt X3501* run: bad thread (3501) X3502 none of the alternative tests of SELECT succeeds X3503 test refinement reports no outcome X3504 refinement returns no value X3505 run-time error %s X3506 run: cannot execute how-to definition X3507* bad FPR_FORMAL (3507) X3508 QUIT may only occur in a command or command-refinement X3509 RETURN may only occur in a function or expression-refinement X3510 REPORT may only occur in a predicate or test-refinement X3511 SUCCEED may only occur in a predicate or test-refinement X3512 FAIL may only occur in a predicate or test-refinement X3513* run: bad node type (3513) X3600 location not initialised X3601 %s hasn't been initialised X3602 key not in table X3603 inserting in non-list X3604 removing from non-list X3605 removing from empty list X3606 selection on empty table X3607* call of location with improper type (3607) X3608* uniquifying text-selection location (3608) X3609* uniquifying comploc (3609) X3610* uniquifying non-location (3610) X3611 text-selection (@ or |) on non-text X3612 in the location t@p or t|p, t does not contain a text X3613 in the location t@p or t|p, p is out of bounds X3614 selection on location of improper type X3615 text-selection (@ or |) out of bounds X3616 putting non-text in text-selection (@ or |) X3617 putting non-compound in compound location X3618 putting compound in compound location of different length X3619 putting in non-location X3620 putting different values in same location X3621 deleting non-location X3622 deleting text-selection (@ or |) location X3623 deleting non-existent location X3624 binding non-location X3625 unbinding non-location X3700 write error (disk full?) X3800 value too big to output X3801* writing value of unknown type (3801) X3802 *** Please answer with '%c' or '%c'\n X3803 *** Just '%c' or '%c', please\n X3804 *** This is your last chance. Take it. I really don't know what you want.\n So answer the question\n X3805 *** Well, I shall assume that your refusal to answer the question means '%c'!\n X3806 End of input encountered during READ command X3807 End of input encountered during READ t RAW X3808 type of expression does not agree with that of EG sample X3809 *** Please try again\n X3900 *** abc: killed by signal\n X3901 *** Oops, I feel suddenly (BURP!) indisposed. I'll call it a day. Sorry.\n X3902 *** Oops, an act of God has occurred compelling me to discontinue service.\n X3903 unexpected arithmetic overflow X4000 cannot create file name for %s X4001 filename and how-to name incompatible for %s X4002 cannot create file %s; need write permission in directory X4003 unable to find file X4004* wrong nodetype of how-to (4004) X4005 there is already a how-to with this name X4006 there is already a permanent location with this name X4007 *** the how-to name is already in use;\n*** should the old how-to be discarded?\n*** (if not you have to change the how-to name)\n X4008 *** the how-to name is already in use for a permanent location;\n*** should that location be deleted?\n*** (if not you have to change the how-to name)\n X4009 I find nothing editible here X4010 no current how-to X4011 *** do you want to visit the version with %c or %c operands?\n X4012 *** you have no write permission in this workspace:\n*** you may not change the how-to\n*** do you still want to display the how-to?\n X4013 *** cannot create file name;\n*** you have to change the how-to name\n X4014 %s isn't a how-to in this workspace X4015* ens_filed() (4015) X4016 no current location X4017 *** you have no write permission in this workspace:\n*** you may not change the location\n*** do you still want to display the location?\n X4018 %s isn't a location in this workspace X4019 value is not a table X4020 in t[k], k is not a text X4021 Press [SPACE] for more, [RETURN] to exit list X4100* stack underflow (4100) X4101* bad call type (4101) X4102* stack clobbered (4102) X4103 You haven't told me HOW TO REPORT %s X4104 You haven't told me HOW TO RETURN %s X4105* invoked how-to has other adicity than invoker (4105) X4106* udfpr with predefined how-to (4106) X4107* formula called with non-function (4107) X4108* proposition called with non-predicate (4108) X4109* extract (4109) X4110 putting non-compound in compound parameter X4111 parameter has wrong length X4112* not a compound in sub_epibreer (4112) X4113* bad nodetype in sub_epibreer (4113) X4114* too many tags in sub_putback (4114) X4115* not a compound in sub_putback (4115) X4116* bad node type in sub_putback (4116) X4117* not a compound in collect_value (4117) X4118* bad node type in collect_value (4118) X4119 on return, part of compound holds no value X4120 value of expression parameter changed X4121* bad def in x_user_command (4121) X4122 You haven't told me HOW TO %s X4200* loctype asked of non-location (4200) X4201* valtype called with unknown type (4201) X4400 in ... i IN e, i contains a non-local name X4500* in cmdline() (4500) X4600 *** %s isn't the name of a location\n X4601 *** %s hasn't been initialised\n X4602 *** %s isn't a table\n X4603 *** Errors while recovering workspace:\n X4604 *** %s: cannot derive a location name\n X4605 *** %s: cannot read this file\n X4606 *** %s: cannot derive a how-to name\n X4607 *** %s: cannot rename this file\n X4608 *** %s: the ABC name for this file is already in use\n X4609 *** %s: cannot create this file\n X4610 *** Errors while recovering the workspace index\n X4611 *** %s: cannot derive an ABC name for this workspace\n X4612 *** %s: the ABC name for this workspace is already in use\n X4700 *** Interrupted\n X6000 Empty copy buffer X6001 Trouble with your how-to, see last line. Hit [interrupt] if you don't want this X6002 Spaces and tabs mixed for indentation; check your program layout X6003 There are still holes left. Please fill or delete these first. X6004 I cannot [goto] that position X6005 Sorry, I could not [goto] that position X6006 You can't use [goto] in recording mode X6007 Cannot insert '%c' X6008 No keystrokes recorded X6009 Keystrokes recorded, use [play] to play back X6010 This redo brought you to an older version. Use [undo] to cancel X6200 Sorry, I can't edit file \"%s\" X6201 excessively nested indentation X6202 indentation messed up X6203 unexpected indentation increase X6204* readsym: ungetc failed (6204) X6300 Cannot save how-to on file \"%s\" X6400 Recording X6401 Copy buffer X6500 Errors in key definitions file:\n X6501 Definition for command %s starts with '%c'. X6502 Definition for command %s would produce an interrupt or suspend. X6503 Definition for command %s would produce an interrupt. X6504 Too many key definitions X6505 no '[' before name X6506 No name after '[' X6507 no ']' after name X6508 opening string quote not found X6509 closing string quote not found in definition X6510 definition string too long X6511 opening string quote not found in representation X6512 closing string quote not found in representation X6513 unprintable character in representation X6514 representation string too long X6515 Name %s not followed by '=' X6516 Unknown command name: %s X6517 Cannot rebind %s in keysfile X6518 No '=' after definition for name %s X6519* too many predefined keys (6519) X6600 *** Bad $TERM or termcap, or dumb terminal\n X6601 *** Bad SCREEN environment\n X6602 *** Cannot reach keyboard or screen\n X6700 Press [SPACE] for more, [RETURN] to exit help X6701 Press [SPACE] or [RETURN] to exit help X6702 *** Cannot find or read help file [%s] X6800 *** Bad tgetent() return value.\n X6801 *** Can't read termcap.\n X6802 *** No description for your terminal.\n X6900 \nUsage: abc [-W ws.group] [-w ws.name]\n X6901 [ -e | -i tab | -o tab | -l | -r | -R | file ...]\n X6902 \nWorkspace Options:\n X6903 -W dir use group of workspaces in 'dir' (default $HOME/abc)\n X6904 -w name start in workspace 'name' (default: last workspace)\n X6905 -w path use 'path' as current workspace (no -W option allowed)\n X6906 \nOther Options:\n X6907 -e Use ${EDITOR} as editor to edit definitions\n X6908 file ... Read commands from file(s)\n X6909 \nSpecial tasks:\n X6910 -i tab Fill table 'tab' with text lines from standard input\n X6911 -o tab Write text lines from table 'tab' to standard output\n X6912 -l List the how-to's in a workspace on standard output\n X6913 -r Recover a workspace when its index is lost\n X6914 -R Recover the index of a group of workspaces\n X6915 \nUse 'abckeys' to change key bindings\n X6916 *** incompatible workspace options\n X6917 *** you have not set your environment variable EDITOR\n X7000 *** can't finish writing suggestion file [%s] X7100* s_up failed (7100) X7101* s_downi failed (7101) X7102* s_down failed (7102) X7103* s_downrite failed (7103) X8000 argument to graphics command not a vector X8001 no graphics hardware available END_OF_FILE if test 18006 -ne `wc -c <'abc/abc.msg'`; then echo shar: \"'abc/abc.msg'\" unpacked with wrong size! fi # end of 'abc/abc.msg' fi if test -f 'abc/bed/e1edoc.c' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'abc/bed/e1edoc.c'\" else echo shar: Extracting \"'abc/bed/e1edoc.c'\" \(15951 characters\) sed "s/^X//" >'abc/bed/e1edoc.c' <<'END_OF_FILE' X/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1986. */ X X#include "b.h" X#include "bedi.h" X#include "etex.h" X#include "feat.h" X#include "bobj.h" X#include "defs.h" X#include "node.h" X#include "erro.h" X#include "gram.h" X#include "keys.h" X#include "queu.h" X#include "supr.h" X#include "tabl.h" X Xextern bool io_exit; Xextern bool slowterminal; X X#define Mod(k) (((k)+MAXHIST) % MAXHIST) X#define Succ(k) (((k)+1) % MAXHIST) X#define Pred(k) (((k)+MAXHIST-1) % MAXHIST) X X#define CANT_SAVE MESS(6300, "Cannot save how-to on file \"%s\"") X Xextern environ *tobesaved; Xextern string savewhere; X XHidden int highwatmark = Maxintlet; X XVisible bool lefttorite; X /* Saves some time in nosuggtoqueue() for read from file */ X X/* X * Edit a unit or target, using the environment offered as a parameter. X */ X XVisible bool Xdofile(ep, filename, linenumber, kind, creating) X environ *ep; X string filename; X int linenumber; X literal kind; X bool creating; X{ X bool read_bad= No; X bool readfile(); X X#ifdef SAVEPOS X if (linenumber <= 0) X linenumber = getpos(filename); X#endif /* SAVEPOS */ X setroot(kind == '=' ? Target_edit : Unit_edit); X savewhere = filename; X tobesaved = (environ*)NULL; X X lefttorite = Yes; X if (!readfile(ep, filename, linenumber, creating)) { X ederr(READ_BAD); X read_bad = Yes; X } X#ifdef USERSUGG X readsugg(ep->focus); X#endif /* USERSUGG */ X lefttorite = No; X X ep->generation = 0; X if (!editdocument(ep, read_bad)) X return No; X if (ep->generation > 0) { X if (!save(ep->focus, filename)) X ederrS(CANT_SAVE, filename); X#ifdef USERSUGG X writesugg(ep->focus); X#endif /* USERSUGG */ X } X#ifdef SAVEPOS X savpos(filename, ep); X#endif /* SAVEPOS */ X savewhere = (char*)NULL; X tobesaved = (environ*)NULL; X return Yes; X} X X X/* X * Call the editor for a given document. X */ X XVisible bool Xeditdocument(ep, bad_file) X environ *ep; X bool bad_file; X{ X int k; X int first = 0; X int last = 0; X int current = 0; X int onscreen = -1; X bool reverse = No; X environ newenv; X int cmd; X bool errors = No; X int undoage = 0; X bool done = No; X int height; X environ history[MAXHIST]; X X Ecopy(*ep, history[0]); X X for (;;) { /* Command interpretation loop */ X if (reverse && onscreen >= 0) X height = history[onscreen].highest; X else X height = history[current].highest; X if (height < highwatmark) highwatmark = height; X if (done) X break; X if (!interrupted && trmavail() <= 0) { X if (onscreen != current) X virtupdate(onscreen < 0 ? (environ*)NULL : &history[onscreen], X &history[current], X reverse && onscreen >= 0 ? X history[onscreen].highest : history[current].highest); X onscreen = current; X highwatmark = Maxintlet; X actupdate(history[current].copyflag ? X history[current].copybuffer : Vnil, X#ifdef RECORDING X history[current].newmacro != Vnil, X#else /* !RECORDING */ X No, X#endif /* !RECORDING */ X No); X } X if (interrupted) break; X#ifdef MENUS X adjusteditmenu( X (bool) (ishole(&history[current])), X (bool) (history[current].copybuffer != Vnil), X (bool) (history[current].copyflag), X (bool) (current != first), X (bool) (current != last) X ); X#endif X cmd = inchar(); X X errors = No; X switch (cmd) { X X case UNDO: X if (current == first) X errors = Yes; X else { X if (onscreen == current) X reverse = Yes; X current = Pred(current); X undoage = Mod(last-current); X } X break; X X case REDO: X if (current == last) X errors = Yes; X else { X if (current == onscreen) X reverse = No; X if (history[Succ(current)].generation < X history[current].generation) X ederr(REDO_OLD); /***** Should refuse altogether??? *****/ X current = Succ(current); X undoage = Mod(last-current); X } X break; X X#ifdef HELPFUL X case HELP: X if (help()) X onscreen = -1; X break; X#endif /* HELPFUL */ X X case SUSPEND: X /* after suspend handled by susphandler() */ X onscreen= -1; X trmundefined(); X if (doctype == D_immcmd) X cmdprompt(CMDPROMPT); X break; X X case REDRAW: X onscreen = -1; X trmundefined(); X break; X X case EOF: X done = Yes; X break; X X case CANCEL: X if (bad_file) { X#ifdef MENUS X unhilite(); X#endif X return No; X } X else if (doctype == D_input || X (doctype == D_immcmd && current == first)) X interrupted= Yes; X else X errors= Yes; X break; X X default: X Ecopy(history[current], newenv); X newenv.highest = Maxintlet; X newenv.changed = No; X if (cmd != EXIT) X errors = !execute(&newenv, cmd) || !checkep(&newenv); X else { X done = Yes; X io_exit= Yes; X } X#ifdef EDITRACE X dumpev(&newenv, "AFTER EXECUTE"); X#endif X if (errors) { X switch (cmd) { X case NEWLINE: X if (newenv.mode == ATEND && !parent(newenv.focus)) { X errors = !checkep(&newenv); X if (!errors) { X#ifdef USERSUGG X check_last_unit(&newenv, current); X#endif X done = Yes; X } X } X break; X#ifdef HELPFUL X case '?': X cmd = HELP; X /* FALL THROUGH: */ X case HELP: X if (help()) X onscreen = -1; X#endif /* HELPFUL */ X } X } X if (errors) X Erelease(newenv); X else { X#ifndef SMALLSYS X if (done) X#ifdef MENUS X if (!terminated) X#endif X done = canexit(&newenv); X if (!done) X io_exit= No; X#endif /* SMALLSYS */ X if (!done && ev_eq(&newenv, &history[current])) { X errors= Yes; X Erelease(newenv); X break; /* don't remember no.ops */ X } X if (newenv.changed) X ++newenv.generation; X last = Succ(last); X current = Succ(current); X if (last == first) { X /* Array full (always after a while). Discard "oldest". */ X if (current == last X || undoage < Mod(current-first)) { X Erelease(history[first]); X first = Succ(first); X if (undoage < MAXHIST) X ++undoage; X } X else { X last = Pred(last); X Erelease(history[last]); X } X } X if (current != last X && newenv.highest < history[current].highest) X history[current].highest = newenv.highest; X /* Move entries beyond current one up. */ X for (k = last; k != current; k = Pred(k)) { X if (Pred(k) == onscreen) X onscreen = k; X Emove(history[Pred(k)], history[k]); X } X Ecopy(newenv, history[current]); X Erelease(history[current]); X } X break; /* default */ X X } /* switch */ X X if (errors X#ifdef HELPFUL X && cmd != HELP X#endif X ) { X if (!slowterminal && isascii(cmd) X && (isprint(cmd) || cmd == ' ')) X ederrC(INS_BAD, cmd); X else X ederr(0); X } X if (savewhere) X tobesaved = &history[current]; X } /* for (;;) */ X X if (onscreen != current) X virtupdate(onscreen < 0 ? (environ*)NULL : &history[onscreen], X &history[current], highwatmark); X actupdate(Vnil, No, Yes); X Erelease(*ep); X Ecopy(history[current], *ep); X if (savewhere) X tobesaved = ep; X for (current = first; current != last; current = Succ(current)) X Erelease(history[current]); X Erelease(history[last]); X#ifdef MENUS X unhilite(); X#endif X return Yes; X} X X/* X * Execute a command, return success or failure. X */ X Xextern bool justgoon; X XHidden bool Xexecute(ep, cmd) X register environ *ep; X register int cmd; X{ X register bool spflag = ep->spflag; X register int i; X environ ev; X char buf[2]; X char ch; X int len; X#ifdef USERSUGG X bool sugg; X int sym= symbol(tree(ep->focus)); X X sugg = sym == Suggestion; X#define ACKSUGG(ep) if (sugg) acksugg(ep) X#define KILLSUGG(ep) if (sugg) killsugg(ep, (string*)NULL); \ X else if (sym==Sugghowname) ackhowsugg(ep) X#else /* !USERSUGG */ X#define ACKSUGG(ep) /* NULL */ X#define KILLSUGG(ep) /* NULL */ X#endif /* !USERSUGG */ X X if (justgoon) X justgoon = isascii(cmd) && islower(cmd); X X#ifdef RECORDING X if (ep->newmacro && cmd != RECORD && cmd != PLAYBACK) { X value t; X buf[0] = cmd; buf[1] = 0; X e_concto(&ep->newmacro, t= mk_etext(buf)); X release(t); X } X#endif /* RECORDING */ X ep->spflag = No; X X switch (cmd) { X X#ifdef RECORDING X case RECORD: X ep->spflag = spflag; X if (ep->newmacro) { /* End definition */ X release(ep->oldmacro); X if (ep->newmacro && e_length(ep->newmacro) > 0) { X ep->oldmacro = ep->newmacro; X edmessage(getmess(REC_OK)); X } X else { X release(ep->newmacro); X ep->oldmacro = Vnil; X } X ep->newmacro = Vnil; X } X else /* Start definition */ X ep->newmacro = mk_etext(""); X return Yes; X X case PLAYBACK: X if (!ep->oldmacro || e_length(ep->oldmacro) <= 0) { X ederr(PLB_NOK); X return No; X } X ep->spflag = spflag; X len= e_length(ep->oldmacro); X for (i = 0; i < len; ++i) { X ch= e_ncharval(i+1, ep->oldmacro); X Ecopy(*ep, ev); X if (execute(ep, ch&0377) && checkep(ep)) X Erelease(ev); X else { X Erelease(*ep); X Emove(ev, *ep); X if (!i) X return No; X ederr(0); /* Just a bell */ X /* The error must be signalled here, because the overall X command (PLAYBACK) succeeds, so the main loop X doesn't ring the bell; but we want to inform the X that not everything was done either. */ X return Yes; X } X } X return Yes; X#endif /* RECORDING */ X X#ifdef GOTOCURSOR X case GOTO: X ACKSUGG(ep); X#ifdef RECORDING X if (ep->newmacro) { X ederr(GOTO_REC); X return No; X } X#endif /* RECORDING */ X return gotocursor(ep); X#endif /* GOTOCURSOR */ X X case NEXT: X ACKSUGG(ep); X return nextarrow(ep); X X case PREVIOUS: X ACKSUGG(ep); X return previous(ep); X X case LEFTARROW: X ACKSUGG(ep); X return leftarrow(ep); X X case RITEARROW: X ACKSUGG(ep); X return ritearrow(ep); X X case WIDEN: X ACKSUGG(ep); X return widen(ep, No); X X case EXTEND: X ACKSUGG(ep); X return extend(ep); X X case FIRST: X ACKSUGG(ep); X return narrow(ep); X X case LAST: X ACKSUGG(ep); X return rnarrow(ep); X X case UPARROW: X ACKSUGG(ep); X return uparrow(ep); X X case DOWNARROW: X ACKSUGG(ep); X return downarrow(ep); X X case UPLINE: X ACKSUGG(ep); X return upline(ep); X X case DOWNLINE: X ACKSUGG(ep); X return downline(ep); X X X case PASTE: X case COPY: X ACKSUGG(ep); X ep->spflag = spflag; X return copyinout(ep); X X case CUT: X case DELETE: X ACKSUGG(ep); X return deltext(ep); X X case ACCEPT: X ACKSUGG(ep); X return accept(ep); X X default: X if (!isascii(cmd) || !isprint(cmd)) X return No; X ep->spflag = spflag; X return ins_char(ep, cmd, islower(cmd) ? toupper(cmd) : -1); X X case ' ': X ep->spflag = spflag; X return ins_char(ep, ' ', -1); X X case NEWLINE: X KILLSUGG(ep); X return ins_newline(ep); X } X} X X X/* X * Initialize an environment variable. Most things are set to 0 or NULL. X */ X XVisible Procedure Xclrenv(ep) X environ *ep; X{ X ep->focus = newpath(NilPath, gram(Optional), 1); X ep->mode = WHOLE; X ep->copyflag = ep->spflag = ep->changed = No; X ep->s1 = ep->s2 = ep->s3 = 0; X ep->highest = Maxintlet; X ep->copybuffer = Vnil; X#ifdef RECORDING X ep->oldmacro = ep->newmacro = Vnil; X#endif /* RECORDING */ X ep->generation = 0; X ep->changed = No; X} X X/* X * Find out if the current position is higher in the tree X * than `ever' before (as remembered in ep->highest). X * The algorithm of pathlength() is repeated here to gain X * some efficiency by stopping as soon as it is clear X * no change can occur. X * (Higher() is called VERY often, so this pays). X */ X XVisible Procedure Xhigher(ep) X register environ *ep; X{ X register path p = ep->focus; X register int pl = 0; X register int max = ep->highest; X X while (p) { X ++pl; X if (pl >= max) X return; X p = parent(p); X } X ep->highest = pl; X} X X#ifndef NDEBUG X X/* X * Issue debug status message. X */ X XVisible Procedure Xdbmess(ep) X register environ *ep; X{ X#ifndef SMALLSYS X char stuff[80]; X register string str = stuff; X X switch (ep->mode) { X case VHOLE: X sprintf(stuff, "VHOLE:%d.%d", ep->s1, ep->s2); X break; X case FHOLE: X sprintf(stuff, "FHOLE:%d.%d", ep->s1, ep->s2); X break; X case ATBEGIN: X str = "ATBEGIN"; X break; X case ATEND: X str = "ATEND"; X break; X case WHOLE: X str = "WHOLE"; X break; X case SUBRANGE: X sprintf(stuff, "SUBRANGE:%d.%d-%d", ep->s1, ep->s2, ep->s3); X break; X case SUBSET: X sprintf(stuff, "SUBSET:%d-%d", ep->s1, ep->s2); X break; X case SUBLIST: X sprintf(stuff, "SUBLIST...%d", ep->s3); X break; X default: X sprintf(stuff, "UNKNOWN:%d,%d,%d,%d", X ep->mode, ep->s1, ep->s2, ep->s3); X } X sprintf(messbuf, X#ifdef SAVEBUF X "%s, %s, wi=%d, hi=%d, (y,x,l)=(%d,%d,%d) %s", X symname(symbol(tree(ep->focus))), X#else /* !SAVEBUF */ X "%d, %s, wi=%d, hi=%d, (y,x,l)=(%d,%d,%d) %s", X symbol(tree(ep->focus)), X#endif /* SAVEBUF */ X str, nodewidth(tree(ep->focus)), ep->highest, X Ycoord(ep->focus), Xcoord(ep->focus), Level(ep->focus), X ep->spflag ? "spflag on" : ""); X#endif /* !SMALLSYS */ X edmessage(messbuf); X} X X#endif /* NDEBUG */ X X#ifndef SMALLSYS X XHidden bool Xcanexit(ep) X environ *ep; X{ X environ ev; X X shrink(ep); X if (ishole(ep)) X VOID deltext(ep); X Ecopy(*ep, ev); X top(&ep->focus); X higher(ep); X ep->mode = WHOLE; X if (findhole(&ep->focus)) { X Erelease(ev); X ederr(EXIT_HOLES); /* There are holes left */ X return No; X } X Erelease(*ep); X Emove(ev, *ep); X return Yes; X} X X XHidden bool Xfindhole(pp) X register path *pp; X{ X register node n = tree(*pp); X X if (Is_etext(n)) X return No; X if (symbol(n) == Hole) X return Yes; X if (!down(pp)) X return No; X for (;;) { X if (findhole(pp)) X return Yes; X if (!rite(pp)) X break; X X } X if (!up(pp)) Abort(); X return No; X} X X#endif /* !SMALLSYS */ X X/* ------------------------------------------------------------------ */ X X#ifdef SAVEBUF X X/* X * Write a node. X */ X X#ifdef DUMPING_QUEUES XVisible Procedure X#else XHidden Procedure X#endif Xwritenode(n, fp) X node n; X FILE *fp; X{ X int nch; X int i; X X if (!n) { X fputs("(0)", fp); X return; X } X if (((value)n)->type == Etex) { X writetext((value)n, fp); X return; X } X nch = nchildren(n); X fprintf(fp, "(%s", symname(symbol(n))); X for (i = 1; i <= nch; ++i) { X putc(',', fp); X writenode(child(n, i), fp); X } X fputc(')', fp); X} X X XHidden Procedure Xwritetext(v, fp) X value v; X FILE *fp; X{ X intlet k, len; X int c; X X Assert(v && Is_etext(v)); X len= e_length(v); X putc('\'', fp); X for (k= 0; k<len; ++k) { X c= e_ncharval(k+1, v); X if (c == ' ' || isprint(c)) { X putc(c, fp); X if (c == '\'' || c == '`') X putc(c, fp); X } X else if (isascii(c)) X fprintf(fp, "`$%d`", c); X } X putc('\'', fp); X} X X XVisible bool Xsavequeue(v, filename) X value v; X string filename; X{ X register FILE *fp; X auto queue q = (queue)v; X register node n; X register bool ok; X register int lines = 0; X X fp = fopen(filename, "w"); X if (!fp) X return No; X q = qcopy(q); X while (!emptyqueue(q)) { X n = queuebehead(&q); X writenode(n, fp); X putc('\n', fp); X ++lines; X noderelease(n); X } X ok = fclose(fp) != EOF; X if (!lines) X /* Try to */ unlink(filename); /***** UNIX! *****/ X return ok; X} X#endif /* SAVEBUF */ X X#ifdef SAVEBUF X#ifdef EDITRACE Xextern FILE *dumpfp; X XVisible Procedure dumpev(ep, m) register environ *ep; string m; X{ X char stuff[80]; X register string str = stuff; X path pa; X node n; X int ich; X static int idump; X X if (dumpfp == NULL) X return; X X idump++; X fprintf(dumpfp, "+++ EV %d: %s +++\n", idump, m); X X switch (ep->mode) { X case VHOLE: X sprintf(str, "VHOLE:%d.%d", ep->s1, ep->s2); X break; X case FHOLE: X sprintf(str, "FHOLE:%d.%d", ep->s1, ep->s2); X break; X case ATBEGIN: X str = "ATBEGIN"; X break; X case ATEND: X str = "ATEND"; X break; X case WHOLE: X str = "WHOLE"; X break; X case SUBRANGE: X sprintf(str, "SUBRANGE:%d.%d-%d", ep->s1, ep->s2, ep->s3); X break; X case SUBSET: X sprintf(str, "SUBSET:%d-%d", ep->s1, ep->s2); X break; X case SUBLIST: X sprintf(str, "SUBLIST...%d", ep->s3); X break; X default: X sprintf(str, "UNKNOWN:%d,%d,%d,%d", X ep->mode, ep->s1, ep->s2, ep->s3); X } X n= tree(ep->focus); X fprintf(dumpfp, X "%s, %s, wi=%d, hi=%d, (y,x,l)=(%d,%d,%d) %s %s\n", X (Is_etext(n) ? "<TEXT> " : symname(symbol(n))), X str, nodewidth(n), ep->highest, X Ycoord(ep->focus), Xcoord(ep->focus), Level(ep->focus), X ep->spflag ? "spflag on" : "", X ep->changed ? "changed" : ""); X writenode(n, dumpfp); X pa= parent(ep->focus); X ich= ichild(ep->focus); X while (pa != NilPath) { X fprintf(dumpfp, " IN PARENT AT %d:\n", ich); X writenode(tree(pa), dumpfp); X ich= ichild(pa); X pa= parent(pa); X } X fprintf(dumpfp, "\n"); X fflush(dumpfp); X} X#endif /*DUMPEV*/ X#endif /*SAVEBUF*/ END_OF_FILE if test 15951 -ne `wc -c <'abc/bed/e1edoc.c'`; then echo shar: \"'abc/bed/e1edoc.c'\" unpacked with wrong size! fi # end of 'abc/bed/e1edoc.c' fi if test -f 'abc/bint1/i1fun.c' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'abc/bint1/i1fun.c'\" else echo shar: Extracting \"'abc/bint1/i1fun.c'\" \(16456 characters\) sed "s/^X//" >'abc/bint1/i1fun.c' <<'END_OF_FILE' X/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1986. */ X X/* Functions defined on numeric values. */ X X#include <errno.h> /* For EDOM and ERANGE */ X X#include "b.h" X#include "feat.h" /* for EXT_RANGE */ X#include "bobj.h" X#include "i0err.h" X#include "i1num.h" X X/* X * The visible routines here implement predefined B arithmetic operators, X * taking one or two numeric values as operands, and returning a numeric X * value. X * No type checking of operands is done: this must be done by the caller. X */ X Xtypedef value (*valfun)(); Xtypedef rational (*ratfun)(); Xtypedef real (*appfun)(); Xtypedef double (*mathfun)(); X X/* X * For the arithmetic functions (+, -, *, /) the same action is needed: X * 1) if both operands are Integral, use function from int_* submodule; X * 2) if both are Exact, use function from rat_* submodule (after possibly X * converting one of them from Integral to Rational); X * 3) otherwise, make both approximate and use function from app_* X * submodule. X * The functions performing the appropriate action for each of the submodules X * are passed as parameters. X * Division is a slight exception, since i/j can be a rational. X * See `quot' below. X */ X XHidden value dyop(u, v, int_fun, rat_fun, app_fun) X value u, v; X valfun int_fun; X ratfun rat_fun; X appfun app_fun; X{ X if (Integral(u) && Integral(v)) /* Use integral operation */ X return (*int_fun)(u, v); X X if (Exact(u) && Exact(v)) { X rational u1, v1, a; X X /* Use rational operation */ X X u1 = Integral(u) ? mk_rat((integer)u, int_1, 0, Yes) : X (rational) Copy(u); X v1 = Integral(v) ? mk_rat((integer)v, int_1, 0, Yes) : X (rational) Copy(v); X a = (*rat_fun)(u1, v1); X Release(u1); X Release(v1); X X if (Denominator(a) == int_1 && Roundsize(a) == 0) { X integer b = (integer) Copy(Numerator(a)); X Release(a); X return (value) b; X } X X return (value) a; X } X X /* Use approximate operation */ X X { X real u1, v1, a; X u1 = Approximate(u) ? (real) Copy(u) : (real) approximate(u); X v1 = Approximate(v) ? (real) Copy(v) : (real) approximate(v); X a = (*app_fun)(u1, v1); X Release(u1); X Release(v1); X X return (value) a; X } X} X X XVisible value sum(u, v) value u, v; { X if (IsSmallInt(u) && IsSmallInt(v)) X return (value) mk_int( X (double)SmallIntVal(u) + (double)SmallIntVal(v)); X return dyop(u, v, (value (*)())int_sum, rat_sum, app_sum); X} X XVisible value diff(u, v) value u, v; { X if (IsSmallInt(u) && IsSmallInt(v)) X return (value) mk_int( X (double)SmallIntVal(u) - (double)SmallIntVal(v)); X return dyop(u, v, (value (*)())int_diff, rat_diff, app_diff); X} X XVisible value prod(u, v) value u, v; { X if (IsSmallInt(u) && IsSmallInt(v)) X return (value) mk_int( X (double)SmallIntVal(u) * (double)SmallIntVal(v)); X return dyop(u, v, (value (*)())int_prod, rat_prod, app_prod); X} X X X/* X * We cannot use int_quot (which performs integer division with truncation). X * Here is the routine we need. X */ X XHidden value xxx_quot(u, v) integer u, v; { X X if (v == int_0) { X interr(ZERO_DIVIDE); X return (value) Copy(u); X } X X return mk_exact(u, v, 0); X} X XVisible value quot(u, v) value u, v; { X return dyop(u, v, xxx_quot, rat_quot, app_quot); X} X X X/* X * Unary minus and abs follow the same principle but with only one operand. X */ X XVisible value negated(u) value u; { X if (IsSmallInt(u)) return mk_integer(-SmallIntVal(u)); X if (Integral(u)) X return (value) int_neg((integer)u); X if (Rational(u)) X return (value) rat_neg((rational)u); X return (value) app_neg((real)u); X} X X XVisible value absval(u) value u; { X if (Integral(u)) { X if (Msd((integer)u) < 0) X return (value) int_neg((integer)u); X } else if (Rational(u)) { X if (Msd(Numerator((rational)u)) < 0) X return (value) rat_neg((rational)u); X } else if (Approximate(u) && Frac((real)u) < 0) X return (value) app_neg((real)u); X X return Copy(u); X} X X X/* X * The remaining operators follow less similar paths and some of X * them contain quite subtle code. X */ X XVisible value mod(u, v) value u, v; { X value q, f, d, p; X X if (v == (value)int_0 || X Rational(v) && Numerator((rational)v) == int_0 || X Approximate(v) && Frac((real)v) == 0) { X interr(MESS(600, "in x mod y, y is zero")); X return Copy(u); X } X X if (Integral(u) && Integral(v)) X return (value) int_mod((integer)u, (integer)v); X X /* Compute `(u/v-floor(u/v))*v', which prevents loss of precision; X don't use `u-v*floor(u/v)', as in the formal definition of `mod'. */ X X q = quot(u, v); X f = floorf(q); X d = diff(q, f); X release(q); X release(f); X p = prod(d, v); X release(d); X X return p; X} X X X/* X * u**v has the most special cases of all the predefined arithmetic functions. X */ X XVisible value power(u, v) value u, v; { X real ru, rv, rw; X if (Exact(u) && (Integral(v) || X /* Next check catches for integers disguised as rationals: */ X Rational(v) && Denominator((rational)v) == int_1)) { X rational a; X integer b = Integral(v) ? (integer)v : Numerator((rational)v); X /* Now b is really an integer. */ X X u = Integral(u) ? (value) mk_rat((integer)u, int_1, 0, Yes) : X Copy(u); X a = rat_power((rational)u, b); X Release(u); X if (Denominator(a) == int_1) { /* Make integral result */ X b = (integer) Copy(Numerator(a)); X Release(a); X return (value)b; X } X return (value)a; X } X X if (Exact(v)) { X integer vn, vd; X int s; X ru = (real) approximate(u); X if (v == (value) int_2) { X /* speed up common formula u**2 */ X rw= app_prod(ru, ru); X Release(ru); X return (value) rw; X } X if (about2_to_integral(ru, v, &rv)) { X /* to speed up reading the value of an approximate X * from a file, the exponent part is stored as X * ~2**expo; X * we want to return the value (0.5, expo+1) to X * prevent loss of precision, but the normal way X * via app_power() isn't good enough; X */ X Release(ru); X return (value) rv; X } X s = (Frac(ru) > 0) - (Frac(ru) < 0); X X if (s < 0) rv = app_neg(ru), Release(ru), ru = rv; X if (Integral(v)) { X vn = (integer)v; X vd = int_1; X } else { X vd = Denominator((rational)v); X if (s < 0 && Even(Lsd(vd))) X interr(NEG_EVEN); X vn = Numerator((rational)v); X } X if (vn == int_0) { X Release(ru); X return one; X } X if (s == 0 && Msd(vn) < 0) { X interr(NEG_POWER); X return (value) ru; X } X if (s < 0 && Even(Lsd(vn))) X s = 1; X rv = (real) approximate(v); X rw = app_power(ru, rv); X Release(ru), Release(rv); X if (s < 0) ru = app_neg(rw), Release(rw), rw = ru; X return (value) rw; X } X X /* Everything else: we now know u or v is approximate */ X X ru = (real) approximate(u); X if (Frac(ru) < 0) { X interr(NEG_EXACT); X return (value) ru; X } X rv = (real) approximate(v); X if (Frac(ru) == 0 && Frac(rv) < 0) { X interr(NEG_POWER); X Release(rv); X return (value) ru; X } X rw = app_power(ru, rv); X Release(ru), Release(rv); X return (value) rw; X} X X X/* X * floor: for approximate numbers app_floor() is used; X * for integers it is a no-op; other exact numbers effectively calculate X * u - (u mod 1). X */ X XVisible value floorf(u) value u; { X integer quo, rem, v; X digit div; X X if (Integral(u)) return Copy(u); X if (Approximate(u)) return (value) app_floor((real)u); X X /* It is a rational number */ X X div = int_ldiv(Numerator((rational)u), Denominator((rational)u), X &quo, &rem); X if (div < 0 && rem != int_0) { /* Correction for negative noninteger */ X v = int_diff(quo, int_1); X Release(quo); X quo = v; X } X Release(rem); X return (value) quo; X} X X X/* X * ceiling x is defined as -floor(-x); X * and that's how it's implemented, except for integers. X */ X XVisible value ceilf(u) value u; { X value v; X if (Integral(u)) return Copy(u); X u = negated(u); X v = floorf(u); X release(u); X u = negated(v); X release(v); X return u; X} X X X/* X * round u is defined as floor(u+0.5), which is what is done here, X * except for integers which are left unchanged; X * for rationals the sum u+0.5 isn't normalized; there is no harm in X * that because of the division in floorf() X */ X XVisible value round1(u) value u; { X value v, w; bool neg = No; X X if (Integral(u)) return Copy(u); X X if (numcomp(u, zero) < 0) { X neg = Yes; X u = negated(u); X } X X if (Approximate(u)) { X value w = approximate((value) rat_half); X v = (value) app_sum((real) u, (real) w); X release(w); X } X else v = (value) ratsumhalf((rational) u); X X w = floorf(v); X release(v); X X if (neg) { X release(u); X w = negated(v=w); X release(v); X } X X return w; X} X X X/* X * u round v is defined as 10**-u * round(v*10**u). X * A complication is that u round v is always printed with exactly u digits X * after the decimal point, even if this involves trailing zeros, X * or if v is an integer. X * Consequently, the result is always kept as a rational, even if it can be X * simplified to an integer, and the size field of the rational number X * (which is made negative to distinguish it from integers, and < -1 to X * distinguish it from approximate numbers) is used to store the number of X * significant digits. X * Thus a size of -2 means a normal rational number, and a size < -2 X * means a rounded number to be printed with (-2 - length) digits X * after the decimal point. This last expression can be retrieved using X * the macro Roundsize(v) which should only be applied to Rational X * numbers. X * X * prod10n() is a routine with does a fast multiplication with a ten power X * and does not simplify a rational result sometimes. X */ X XVisible value round2(n, v) value n, v; { X value w; X int i; X X if (!Integral(n)) { X interr(MESS(601, "in n round x, n is not an integer")); X i = 0; X } else X i = propintlet(intval(n)); X X w = Approximate(v) ? exactly(v) : copy(v); X X v = prod10n(w, i, No); X /* v will be rounded, so it isn't simplified if a rational */ X release(w); X X v = round1(w = v); X release(w); X X v = prod10n(w = v, -i, Yes); X release(w); X X if (i > 0) { /* Set number of digits to be printed */ X if (propintlet(-2 - i) < -2) { X if (Rational(v)) X Length(v) = -2 - i; X else if (Integral(v)) { X w = v; X v = mk_exact((integer) w, int_1, i); X release(w); X } X } X } X X return v; X} X X X/* X * sign u inspects the sign of either u, u's numerator or u's fractional part. X */ X XVisible value signum(u) value u; { X int s; X X if (Exact(u)) { X if (Rational(u)) X u = (value) Numerator((rational)u); X s = u==(value)int_0 ? 0 : Msd((integer)u) < 0 ? -1 : 1; X } else X s = Frac((real)u) > 0 ? 1 : Frac((real)u) < 0 ? -1 : 0; X X return MkSmallInt(s); X} X X X/* X * ~u makes an approximate number of any numerical value. X */ X XVisible value approximate(u) value u; { X if (Approximate(u)) X return Copy(u); X else if (IsSmallInt(u)) X return (value) mk_approx((double) SmallIntVal(u), 0.0); X else X return app_frexp(u); X} X X X/* X * exact(v) returns whether a number isn'y approximate X */ X XVisible bool exact(v) value v; { X return (bool) Exact(v); X} X X/* X * numerator v returns the numerator of v, whenever v is an exact number. X * For integers, that is v itself. X */ X XVisible value numerator(v) value v; { X if (!Exact(v)) { X interr(MESS(602, "in */n, n is an approximate number")); X return zero; X } X X if (Integral(v)) return Copy(v); X X return Copy(Numerator((rational)v)); X} X X X/* X * The denominator of v, whenever v is an exact number. X * For integers, that is 1. X */ X XVisible value denominator(v) value v; { X if (!Exact(v)) { X interr(MESS(603, "in /*n, n is an approximate number")); X return zero; X } X X if (Integral(v)) return one; X X return Copy(Denominator((rational)v)); X} X X X/* X * u root v is defined as v**(1/u), where u is usually but need not be X * an integer. X */ X XVisible value root2(u, v) value u, v; { X if (u == (value)int_0 || X Rational(u) && Numerator((rational)u) == int_0 || X Approximate(u) && Frac((real)u) == 0) { X interr(MESS(604, "in n root x, n is zero")); X v = Copy(v); X } else { X u = quot((value)int_1, u); X v = power(v, u); X release(u); X } X X return v; X} X X/* root x is computed more exactly than n root x, by doing X one iteration step extra. This ~guarantees root(n**2) = n. */ X XVisible value root1(v) value v; { X value r, v_over_r, theirsum, result; X if (numcomp(v, zero) < 0) { X interr(MESS(605, "in root x, x is negative")); X return Copy(v); X } X r = root2((value)int_2, v); X if (Approximate(r) && Frac((real)r) == 0.0) return (value)r; X v_over_r = quot(v, r); X theirsum = sum(r, v_over_r), release(r), release(v_over_r); X result = quot(theirsum, (value)int_2), release(theirsum); X return result; X} X X/* The rest of the mathematical functions */ X XVisible value pi() { return (value) mk_approx(3.141592653589793238463, 0.0); } XVisible value e() { return (value) mk_approx(2.718281828459045235360, 0.0); } X XHidden real over_two_pi(v) value v; { X real two_pi = mk_approx(6.283185307179586476926, 0.0); X real w = (real) approximate(v); X real res = app_quot(w, two_pi); X Release(two_pi); Release(w); X return res; X} XHidden value trig(u, v, ffun, zeroflag) X value u, v; X mathfun ffun; X bool zeroflag; X{ X real w; X double expo, frac, x, result; X extern int errno; X X X if (u != Vnil) { /* dyadic version */ X real f = over_two_pi(u); X real rv = (real) approximate(v); X w = app_quot(rv, f); /* check on f<>0 (= u<>0) in i3fpr.c */ X Release(f); Release(rv); X } X else { X w = (real) approximate(v); X } X expo = Expo(w); frac = Frac(w); X if (expo <= Minexpo/2) { X if (zeroflag) return (value) w; /* sin small x = x, etc. */ X frac = 0, expo = 0; X } X Release(w); X if (expo > Maxexpo) errno = EDOM; X else { X x = ldexp(frac, (int)expo); X if (x >= Maxtrig || x <= -Maxtrig) errno = EDOM; X else { X errno = 0; X result = (*ffun)(x); X } X } X if (errno != 0) { X if (errno == ERANGE) X interr(MESS(606, "result of math function too large")); X else if (errno == EDOM) X interr(MESS(607, "argument to math function too large")); X else interr(MESS(608, "math library error")); X return Copy(app_0); X } X return (value) mk_approx(result, 0.0); X} X XVisible value sin1(v) value v; { return trig(Vnil, v, sin, Yes); } XVisible value cos1(v) value v; { return trig(Vnil, v, cos, No); } XVisible value tan1(v) value v; { return trig(Vnil, v, tan, Yes); } XVisible value sin2(u, v) value u, v; { return trig(u, v, sin, Yes); } XVisible value cos2(u, v) value u, v; { return trig(u, v, cos, No); } XVisible value tan2(u, v) value u, v; { return trig(u, v, tan, Yes); } X XVisible value arctan1(v) value v; { X real w = (real) approximate(v); X double expo = Expo(w), frac = Frac(w); X if (expo <= Minexpo + 2) return (value) w; /* atan of small x = x */ X Release(w); X if (expo > Maxexpo) expo = Maxexpo; X return (value) mk_approx(atan(ldexp(frac, (int)expo)), 0.0); X} X XVisible value arctan2(u, v) value u, v; { X real av = (real) arctan1(v); X real f = over_two_pi(u); X real r = app_prod(av, f); X Release(av); Release(f); X return (value) r; X} X XHidden double atn2(x, y) double x, y; { X if (x == 0.0 && y == 0.0) X return 0.0; X else X return atan2(x, y); X} X XVisible value angle1(u, v) value u, v; { X real ru = (real) approximate(u), rv = (real) approximate(v); X double uexpo = Expo(ru), ufrac = Frac(ru); X double vexpo = Expo(rv), vfrac = Frac(rv); X Release(ru), Release(rv); X if (uexpo > Maxexpo) uexpo = Maxexpo; X if (vexpo > Maxexpo) vexpo = Maxexpo; X return (value) mk_approx( X atn2( X vexpo < Minexpo ? 0.0 : ldexp(vfrac, (int)vexpo), X uexpo < Minexpo ? 0.0 : ldexp(ufrac, (int)uexpo)), X 0.0); X} X XVisible value angle2(c, u, v) value c, u, v; { X real av = (real) angle1(u, v); X real f = over_two_pi(c); X real r = app_prod(av, f); X Release(av); Release(f); X return (value) r; X} X XVisible value radius(u, v) value u, v; { X real x = (real) approximate(u); X real y = (real) approximate(v); X real x2 = app_prod(x, x); X real y2 = app_prod(y, y); X real x2y2 = app_sum(x2, y2); X value rad = root1((value) x2y2); X Release(x); Release(y); X Release(x2); Release(y2); Release(x2y2); X return rad; X} X XVisible value exp1(v) value v; { X real w = (real) approximate(v); X real x = app_exp(w); X Release(w); X return (value) x; X} X XVisible value log1(v) value v; { X real w, x; X if (numcomp(v, zero) <= 0) { X interr(MESS(609, "in log x, x <= 0")); X return copy(zero); X } X w = (real) approximate(v); X x = app_log(w); X Release(w); X return (value) x; X} X XVisible value log2(u, v) value u, v;{ X value w; X if (numcomp(u, zero) <= 0) { X interr(MESS(610, "in b log x, b <= 0")); X return copy(zero); X } X if (numcomp(v, zero) <= 0) { X interr(MESS(611, "in b log x, x <= 0")); X return copy(zero); X } X u = log1(u); X v = log1(v); X w = quot(v, u); X release(u), release(v); X return w; X} X X/* exactly() converts a approximate number to an exact number */ X XVisible value exactly(v) value v; { X if (exact(v)) X return Copy(v); X else X return app_exactly((real) v); X} END_OF_FILE if test 16456 -ne `wc -c <'abc/bint1/i1fun.c'`; then echo shar: \"'abc/bint1/i1fun.c'\" unpacked with wrong size! fi # end of 'abc/bint1/i1fun.c' fi if test -f 'abc/ch_config' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'abc/ch_config'\" else echo shar: Extracting \"'abc/ch_config'\" \(230 characters\) sed "s/^X//" >'abc/ch_config' <<'END_OF_FILE' X: 'Check if we are cross compiling' X Xcase $1 in X'') exit 0;; X*) echo "Please compile and run mkconfig on the destination machine" X echo "and copy the results to ./$2." X echo "Then call 'make all install'" X echo " " X exit 1;; Xesac END_OF_FILE if test 230 -ne `wc -c <'abc/ch_config'`; then echo shar: \"'abc/ch_config'\" unpacked with wrong size! fi chmod +x 'abc/ch_config' # end of 'abc/ch_config' fi echo shar: End of archive 10 \(of 25\). cp /dev/null ark10isdone MISSING="" for I in 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 ; do if test ! -f ark${I}isdone ; then MISSING="${MISSING} ${I}" fi done if test "${MISSING}" = "" ; then echo You have unpacked all 25 archives. rm -f ark[1-9]isdone ark[1-9][0-9]isdone else echo You still must unpack the following archives: echo " " ${MISSING} fi exit 0 # Just in case... -- Please send comp.sources.unix-related mail to rsalz@uunet.uu.net. Use a domain-based address or give alternate paths, or you may lose out.