LIB.TXT
上传用户:jnzhq888
上传日期:2007-01-18
资源大小:51694k
文件大小:1006k
源码类别:

操作系统开发

开发平台:

WINDOWS

  1. 15164
  2. 15165 STATIC CHAR             NIL[] = "";
  3. 15166 STATIC CONST CHAR       *Input = NIL;
  4. 15167 STATIC CHAR             *Line;
  5. 15168 STATIC CONST char       *Prompt;
  6. 15169 STATIC CHAR             *Yanked;
  7. 15170 STATIC char             *Screen;
  8. 15171 STATIC char             NEWLINE[]= CRLF;
  9. 15172 STATIC HISTORY          H;
  10. 15173 STATIC int              Repeat;
  11. 15174 STATIC int              End;
  12. 15175 STATIC int              Mark;
  13. 15176 STATIC int              OldPoint;
  14. 15177 STATIC int              Point;
  15. 15178 STATIC int              PushBack;
  16. 15179 STATIC int              Pushed;
  17. 15180 STATIC int              Signal;
  18. 15181 FORWARD KEYMAP          Map[33];
  19. 15182 FORWARD KEYMAP          MetaMap[17];
  20. 15183 STATIC SIZE_T           Length;
  21. 15184 STATIC SIZE_T           ScreenCount;
  22. 15185 STATIC SIZE_T           ScreenSize;
  23. 15186 STATIC char             *backspace;
  24. 15187 STATIC int              TTYwidth;
  25. 15188 STATIC int              TTYrows;
  26. 15189
  27. 15190 /* Display print 8-bit chars as `M-x' or as the actual 8-bit char? */
  28. 15191 int             rl_meta_chars = 0;
  29. 15192
  30. 15193 /*
  31. 15194 **  Declarations.
  32. 15195 */
  33. 15196 STATIC CHAR     *editinput();
  34. 15197 extern int      read();
  35. 15198 extern int      write();
  36. 15199 #if     defined(USE_TERMCAP)
  37. 15200 extern char     *getenv();
  38. 15201 extern char     *tgetstr();
  39. 15202 extern int      tgetent();
  40. 15203 #endif  /* defined(USE_TERMCAP) */
  41. 15204
  42. 15205 /*
  43. 15206 **  TTY input/output functions.
  44. 15207 */
  45. 15208
  46. 15209 STATIC void
  47. 15210 TTYflush()
  48. 15211 {
  49. 15212     if (ScreenCount) {
  50. 15213         (void)write(1, Screen, ScreenCount);
  51. 15214         ScreenCount = 0;
  52. 15215     }
  53. 15216 }
  54. 15218 STATIC void
  55. 15219 TTYput(c)
  56. 15220     CHAR        c;
  57. 15221 {
  58. 15222     Screen[ScreenCount] = c;
  59. 15223     if (++ScreenCount >= ScreenSize - 1) {
  60. 15224         ScreenSize += SCREEN_INC;
  61. 15225         RENEW(Screen, char, ScreenSize);
  62. 15226     }
  63. 15227 }
  64. 15229 STATIC void
  65. 15230 TTYputs(p)
  66. 15231     CHAR        *p;
  67. 15232 {
  68. 15233     while (*p)
  69. 15234         TTYput(*p++);
  70. 15235 }
  71. 15237 STATIC void
  72. 15238 TTYshow(c)
  73. 15239     CHAR        c;
  74. 15240 {
  75. 15241     if (c == DEL) {
  76. 15242         TTYput('^');
  77. 15243         TTYput('?');
  78. 15244     }
  79. 15245     else if (ISCTL(c)) {
  80. 15246         TTYput('^');
  81. 15247         TTYput(UNCTL(c));
  82. 15248     }
  83. 15249     else if (rl_meta_chars && ISMETA(c)) {
  84. 15250         TTYput('M');
  85. 15251         TTYput('-');
  86. 15252         TTYput(UNMETA(c));
  87. 15253     }
  88. 15254     else
  89. 15255         TTYput(c);
  90. 15256 }
  91. 15258 STATIC void
  92. 15259 TTYstring(p)
  93. 15260     CHAR        *p;
  94. 15261 {
  95. 15262     while (*p)
  96. 15263         TTYshow(*p++);
  97. 15264 }
  98. 15266 STATIC unsigned int
  99. 15267 TTYget()
  100. 15268 {
  101. 15269     CHAR        c;
  102. 15270
  103. 15271     TTYflush();
  104. 15272     if (Pushed) {
  105. 15273         Pushed = 0;
  106. 15274         return PushBack;
  107. 15275     }
  108. 15276     if (*Input)
  109. 15277         return *Input++;
  110. 15278     return read(0, &c, (SIZE_T)1) == 1 ? c : EOF;
  111. 15279 }
  112. 15281 #define TTYback()       (backspace ? TTYputs((CHAR *)backspace) : TTYput('b'))
  113. 15282
  114. 15283 STATIC void
  115. 15284 TTYbackn(n)
  116. 15285     int         n;
  117. 15286 {
  118. 15287     while (--n >= 0)
  119. 15288         TTYback();
  120. 15289 }
  121. 15291 STATIC void
  122. 15292 TTYinfo()
  123. 15293 {
  124. 15294     static int          init;
  125. 15295 #if     defined(USE_TERMCAP)
  126. 15296     char                *term;
  127. 15297     char                buff[2048];
  128. 15298     char                *bp;
  129. 15299 #endif  /* defined(USE_TERMCAP) */
  130. 15300 #if     defined(TIOCGWINSZ)
  131. 15301     struct winsize      W;
  132. 15302 #endif  /* defined(TIOCGWINSZ) */
  133. 15303
  134. 15304     if (init) {
  135. 15305 #if     defined(TIOCGWINSZ)
  136. 15306         /* Perhaps we got resized. */
  137. 15307         if (ioctl(0, TIOCGWINSZ, &W) >= 0
  138. 15308          && W.ws_col > 0 && W.ws_row > 0) {
  139. 15309             TTYwidth = (int)W.ws_col;
  140. 15310             TTYrows = (int)W.ws_row;
  141. 15311         }
  142. 15312 #endif  /* defined(TIOCGWINSZ) */
  143. 15313         return;
  144. 15314     }
  145. 15315     init++;
  146. 15316
  147. 15317     TTYwidth = TTYrows = 0;
  148. 15318 #if     defined(USE_TERMCAP)
  149. 15319     bp = &buff[0];
  150. 15320     if ((term = getenv("TERM")) == NULL)
  151. 15321         term = "dumb";
  152. 15322     if (tgetent(buff, term) < 0) {
  153. 15323        TTYwidth = SCREEN_WIDTH;
  154. 15324        TTYrows = SCREEN_ROWS;
  155. 15325        return;
  156. 15326     }
  157. 15327     if ((backspace = tgetstr("le", &bp)) != NULL)
  158. 15328         backspace = strdup(backspace);
  159. 15329     TTYwidth = tgetnum("co");
  160. 15330     TTYrows = tgetnum("li");
  161. 15331 #endif  /* defined(USE_TERMCAP) */
  162. 15332
  163. 15333 #if     defined(TIOCGWINSZ)
  164. 15334     if (ioctl(0, TIOCGWINSZ, &W) >= 0) {
  165. 15335         TTYwidth = (int)W.ws_col;
  166. 15336         TTYrows = (int)W.ws_row;
  167. 15337     }
  168. 15338 #endif  /* defined(TIOCGWINSZ) */
  169. 15339
  170. 15340     if (TTYwidth <= 0 || TTYrows <= 0) {
  171. 15341         TTYwidth = SCREEN_WIDTH;
  172. 15342         TTYrows = SCREEN_ROWS;
  173. 15343     }
  174. 15344 }
  175. 15345
  176. 15346
  177. 15347 /*
  178. 15348 **  Print an array of words in columns.
  179. 15349 */
  180. 15350 STATIC void
  181. 15351 columns(ac, av)
  182. 15352     int         ac;
  183. 15353     CHAR        **av;
  184. 15354 {
  185. 15355     CHAR        *p;
  186. 15356     int         i;
  187. 15357     int         j;
  188. 15358     int         k;
  189. 15359     int         len;
  190. 15360     int         skip;
  191. 15361     int         longest;
  192. 15362     int         cols;
  193. 15363
  194. 15364     /* Find longest name, determine column count from that. */
  195. 15365     for (longest = 0, i = 0; i < ac; i++)
  196. 15366         if ((j = strlen((char *)av[i])) > longest)
  197. 15367             longest = j;
  198. 15368     cols = TTYwidth / (longest + 3);
  199. 15369
  200. 15370     TTYputs((CHAR *)NEWLINE);
  201. 15371     for (skip = ac / cols + 1, i = 0; i < skip; i++) {
  202. 15372         for (j = i; j < ac; j += skip) {
  203. 15373             for (p = av[j], len = strlen((char *)p), k = len; --k >= 0; p++)
  204. 15374                 TTYput(*p);
  205. 15375             if (j + skip < ac)
  206. 15376                 while (++len < longest + 3)
  207. 15377                     TTYput(' ');
  208. 15378         }
  209. 15379         TTYputs((CHAR *)NEWLINE);
  210. 15380     }
  211. 15381 }
  212. 15383 STATIC void
  213. 15384 reposition()
  214. 15385 {
  215. 15386     int         i;
  216. 15387     CHAR        *p;
  217. 15388
  218. 15389     TTYput('r');
  219. 15390     TTYputs((CONST CHAR *)Prompt);
  220. 15391     for (i = Point, p = Line; --i >= 0; p++)
  221. 15392         TTYshow(*p);
  222. 15393 }
  223. 15395 STATIC void
  224. 15396 left(Change)
  225. 15397     STATUS      Change;
  226. 15398 {
  227. 15399     TTYback();
  228. 15400     if (Point) {
  229. 15401         if (ISCTL(Line[Point - 1]))
  230. 15402             TTYback();
  231. 15403         else if (rl_meta_chars && ISMETA(Line[Point - 1])) {
  232. 15404             TTYback();
  233. 15405             TTYback();
  234. 15406         }
  235. 15407     }
  236. 15408     if (Change == CSmove)
  237. 15409         Point--;
  238. 15410 }
  239. 15412 STATIC void
  240. 15413 right(Change)
  241. 15414     STATUS      Change;
  242. 15415 {
  243. 15416     TTYshow(Line[Point]);
  244. 15417     if (Change == CSmove)
  245. 15418         Point++;
  246. 15419 }
  247. 15421 STATIC STATUS
  248. 15422 ring_bell()
  249. 15423 {
  250. 15424     TTYput('7');
  251. 15425     TTYflush();
  252. 15426     return CSstay;
  253. 15427 }
  254. 15429 STATIC STATUS
  255. 15430 do_macro(c)
  256. 15431     unsigned int        c;
  257. 15432 {
  258. 15433     CHAR                name[4];
  259. 15434
  260. 15435     name[0] = '_';
  261. 15436     name[1] = c;
  262. 15437     name[2] = '_';
  263. 15438     name[3] = '';
  264. 15439
  265. 15440     if ((Input = (CHAR *)getenv((char *)name)) == NULL) {
  266. 15441         Input = NIL;
  267. 15442         return ring_bell();
  268. 15443     }
  269. 15444     return CSstay;
  270. 15445 }
  271. 15447 STATIC STATUS
  272. 15448 do_forward(move)
  273. 15449     STATUS      move;
  274. 15450 {
  275. 15451     int         i;
  276. 15452     CHAR        *p;
  277. 15453
  278. 15454     i = 0;
  279. 15455     do {
  280. 15456         p = &Line[Point];
  281. 15457         for ( ; Point < End && (*p == ' ' || !isalnum(*p)); Point++, p++)
  282. 15458             if (move == CSmove)
  283. 15459                 right(CSstay);
  284. 15460
  285. 15461         for (; Point < End && isalnum(*p); Point++, p++)
  286. 15462             if (move == CSmove)
  287. 15463                 right(CSstay);
  288. 15464
  289. 15465         if (Point == End)
  290. 15466             break;
  291. 15467     } while (++i < Repeat);
  292. 15468
  293. 15469     return CSstay;
  294. 15470 }
  295. 15472 STATIC STATUS
  296. 15473 do_case(type)
  297. 15474     CASE        type;
  298. 15475 {
  299. 15476     int         i;
  300. 15477     int         end;
  301. 15478     int         count;
  302. 15479     CHAR        *p;
  303. 15480
  304. 15481     (void)do_forward(CSstay);
  305. 15482     if (OldPoint != Point) {
  306. 15483         if ((count = Point - OldPoint) < 0)
  307. 15484             count = -count;
  308. 15485         Point = OldPoint;
  309. 15486         if ((end = Point + count) > End)
  310. 15487             end = End;
  311. 15488         for (i = Point, p = &Line[i]; i < end; i++, p++) {
  312. 15489             if (type == TOupper) {
  313. 15490                 if (islower(*p))
  314. 15491                     *p = toupper(*p);
  315. 15492             }
  316. 15493             else if (isupper(*p))
  317. 15494                 *p = tolower(*p);
  318. 15495             right(CSmove);
  319. 15496         }
  320. 15497     }
  321. 15498     return CSstay;
  322. 15499 }
  323. 15501 STATIC STATUS
  324. 15502 case_down_word()
  325. 15503 {
  326. 15504     return do_case(TOlower);
  327. 15505 }
  328. 15507 STATIC STATUS
  329. 15508 case_up_word()
  330. 15509 {
  331. 15510     return do_case(TOupper);
  332. 15511 }
  333. 15513 STATIC void
  334. 15514 ceol()
  335. 15515 {
  336. 15516     int         extras;
  337. 15517     int         i;
  338. 15518     CHAR        *p;
  339. 15519
  340. 15520     for (extras = 0, i = Point, p = &Line[i]; i <= End; i++, p++) {
  341. 15521         TTYput(' ');
  342. 15522         if (ISCTL(*p)) {
  343. 15523             TTYput(' ');
  344. 15524             extras++;
  345. 15525         }
  346. 15526         else if (rl_meta_chars && ISMETA(*p)) {
  347. 15527             TTYput(' ');
  348. 15528             TTYput(' ');
  349. 15529             extras += 2;
  350. 15530         }
  351. 15531     }
  352. 15532
  353. 15533     for (i += extras; i > Point; i--)
  354. 15534         TTYback();
  355. 15535 }
  356. 15537 STATIC void
  357. 15538 clear_line()
  358. 15539 {
  359. 15540     Point = -strlen(Prompt);
  360. 15541     TTYput('r');
  361. 15542     ceol();
  362. 15543     Point = 0;
  363. 15544     End = 0;
  364. 15545     Line[0] = '';
  365. 15546 }
  366. 15548 STATIC STATUS
  367. 15549 insert_string(p)
  368. 15550     CHAR        *p;
  369. 15551 {
  370. 15552     SIZE_T      len;
  371. 15553     int         i;
  372. 15554     CHAR        *new;
  373. 15555     CHAR        *q;
  374. 15556
  375. 15557     len = strlen((char *)p);
  376. 15558     if (End + len >= Length) {
  377. 15559         if ((new = NEW(CHAR, Length + len + MEM_INC)) == NULL)
  378. 15560             return CSstay;
  379. 15561         if (Length) {
  380. 15562             COPYFROMTO(new, Line, Length);
  381. 15563             DISPOSE(Line);
  382. 15564         }
  383. 15565         Line = new;
  384. 15566         Length += len + MEM_INC;
  385. 15567     }
  386. 15568
  387. 15569     for (q = &Line[Point], i = End - Point; --i >= 0; )
  388. 15570         q[len + i] = q[i];
  389. 15571     COPYFROMTO(&Line[Point], p, len);
  390. 15572     End += len;
  391. 15573     Line[End] = '';
  392. 15574     TTYstring(&Line[Point]);
  393. 15575     Point += len;
  394. 15576
  395. 15577     return Point == End ? CSstay : CSmove;
  396. 15578 }
  397. 15580 STATIC STATUS
  398. 15581 redisplay()
  399. 15582 {
  400. 15583     TTYputs((CONST CHAR *)NEWLINE);
  401. 15584     TTYputs((CONST CHAR *)Prompt);
  402. 15585     TTYstring(Line);
  403. 15586     return CSmove;
  404. 15587 }
  405. 15589 STATIC STATUS
  406. 15590 toggle_meta_mode()
  407. 15591 {
  408. 15592     rl_meta_chars = ! rl_meta_chars;
  409. 15593     return redisplay();
  410. 15594 }
  411. 15595
  412. 15596
  413. 15597 STATIC CHAR *
  414. 15598 next_hist()
  415. 15599 {
  416. 15600     return H.Pos >= H.Size - 1 ? NULL : H.Lines[++H.Pos];
  417. 15601 }
  418. 15603 STATIC CHAR *
  419. 15604 prev_hist()
  420. 15605 {
  421. 15606     return H.Pos == 0 ? NULL : H.Lines[--H.Pos];
  422. 15607 }
  423. 15609 STATIC STATUS
  424. 15610 do_insert_hist(p)
  425. 15611     CHAR        *p;
  426. 15612 {
  427. 15613     if (p == NULL)
  428. 15614         return ring_bell();
  429. 15615     Point = 0;
  430. 15616     reposition();
  431. 15617     ceol();
  432. 15618     End = 0;
  433. 15619     return insert_string(p);
  434. 15620 }
  435. 15622 STATIC STATUS
  436. 15623 do_hist(move)
  437. 15624     CHAR        *(*move)();
  438. 15625 {
  439. 15626     CHAR        *p;
  440. 15627     int         i;
  441. 15628
  442. 15629     i = 0;
  443. 15630     do {
  444. 15631         if ((p = (*move)()) == NULL)
  445. 15632             return ring_bell();
  446. 15633     } while (++i < Repeat);
  447. 15634     return do_insert_hist(p);
  448. 15635 }
  449. 15637 STATIC STATUS
  450. 15638 h_next()
  451. 15639 {
  452. 15640     return do_hist(next_hist);
  453. 15641 }
  454. 15643 STATIC STATUS
  455. 15644 h_prev()
  456. 15645 {
  457. 15646     return do_hist(prev_hist);
  458. 15647 }
  459. 15649 STATIC STATUS
  460. 15650 h_first()
  461. 15651 {
  462. 15652     return do_insert_hist(H.Lines[H.Pos = 0]);
  463. 15653 }
  464. 15655 STATIC STATUS
  465. 15656 h_last()
  466. 15657 {
  467. 15658     return do_insert_hist(H.Lines[H.Pos = H.Size - 1]);
  468. 15659 }
  469. 15661 /*
  470. 15662 **  Return zero if pat appears as a substring in text.
  471. 15663 */
  472. 15664 STATIC int
  473. 15665 substrcmp(text, pat, len)
  474. 15666     char        *text;
  475. 15667     char        *pat;
  476. 15668     int         len;
  477. 15669 {
  478. 15670     char        c;
  479. 15671
  480. 15672     if ((c = *pat) == '')
  481. 15673         return *text == '';
  482. 15674     for ( ; *text; text++)
  483. 15675         if (*text == c && strncmp(text, pat, len) == 0)
  484. 15676             return 0;
  485. 15677     return 1;
  486. 15678 }
  487. 15680 STATIC CHAR *
  488. 15681 search_hist(search, move)
  489. 15682     CHAR        *search;
  490. 15683     CHAR        *(*move)();
  491. 15684 {
  492. 15685     static CHAR *old_search;
  493. 15686     int         len;
  494. 15687     int         pos;
  495. 15688     int         (*match)();
  496. 15689     char        *pat;
  497. 15690
  498. 15691     /* Save or get remembered search pattern. */
  499. 15692     if (search && *search) {
  500. 15693         if (old_search)
  501. 15694             DISPOSE(old_search);
  502. 15695         old_search = (CHAR *)strdup((char *)search);
  503. 15696     }
  504. 15697     else {
  505. 15698         if (old_search == NULL || *old_search == '')
  506. 15699             return NULL;
  507. 15700         search = old_search;
  508. 15701     }
  509. 15702
  510. 15703     /* Set up pattern-finder. */
  511. 15704     if (*search == '^') {
  512. 15705         match = strncmp;
  513. 15706         pat = (char *)(search + 1);
  514. 15707     }
  515. 15708     else {
  516. 15709         match = substrcmp;
  517. 15710         pat = (char *)search;
  518. 15711     }
  519. 15712     len = strlen(pat);
  520. 15713
  521. 15714     for (pos = H.Pos; (*move)() != NULL; )
  522. 15715         if ((*match)((char *)H.Lines[H.Pos], pat, len) == 0)
  523. 15716             return H.Lines[H.Pos];
  524. 15717     H.Pos = pos;
  525. 15718     return NULL;
  526. 15719 }
  527. 15721 STATIC STATUS
  528. 15722 h_search()
  529. 15723 {
  530. 15724     static int  Searching;
  531. 15725     CONST char  *old_prompt;
  532. 15726     CHAR        *(*move)();
  533. 15727     CHAR        *p;
  534. 15728
  535. 15729     if (Searching)
  536. 15730         return ring_bell();
  537. 15731     Searching = 1;
  538. 15732
  539. 15733     clear_line();
  540. 15734     old_prompt = Prompt;
  541. 15735     Prompt = "Search: ";
  542. 15736     TTYputs((CONST CHAR *)Prompt);
  543. 15737     move = Repeat == NO_ARG ? prev_hist : next_hist;
  544. 15738     p = editinput();
  545. 15739     Prompt = old_prompt;
  546. 15740     Searching = 0;
  547. 15741     TTYputs((CONST CHAR *)Prompt);
  548. 15742     if (p == NULL && Signal > 0) {
  549. 15743         Signal = 0;
  550. 15744         clear_line();
  551. 15745         return redisplay();
  552. 15746     }
  553. 15747     p = search_hist(p, move);
  554. 15748     clear_line();
  555. 15749     if (p == NULL) {
  556. 15750         (void)ring_bell();
  557. 15751         return redisplay();
  558. 15752     }
  559. 15753     return do_insert_hist(p);
  560. 15754 }
  561. 15756 STATIC STATUS
  562. 15757 fd_char()
  563. 15758 {
  564. 15759     int         i;
  565. 15760
  566. 15761     i = 0;
  567. 15762     do {
  568. 15763         if (Point >= End)
  569. 15764             break;
  570. 15765         right(CSmove);
  571. 15766     } while (++i < Repeat);
  572. 15767     return CSstay;
  573. 15768 }
  574. 15770 STATIC void
  575. 15771 save_yank(begin, i)
  576. 15772     int         begin;
  577. 15773     int         i;
  578. 15774 {
  579. 15775     if (Yanked) {
  580. 15776         DISPOSE(Yanked);
  581. 15777         Yanked = NULL;
  582. 15778     }
  583. 15779
  584. 15780     if (i < 1)
  585. 15781         return;
  586. 15782
  587. 15783     if ((Yanked = NEW(CHAR, (SIZE_T)i + 1)) != NULL) {
  588. 15784         COPYFROMTO(Yanked, &Line[begin], i);
  589. 15785         Yanked[i] = '';
  590. 15786     }
  591. 15787 }
  592. 15789 STATIC STATUS
  593. 15790 delete_string(count)
  594. 15791     int         count;
  595. 15792 {
  596. 15793     int         i;
  597. 15794     CHAR        *p;
  598. 15795
  599. 15796     if (count <= 0 || End == Point)
  600. 15797         return ring_bell();
  601. 15798
  602. 15799     if (count == 1 && Point == End - 1) {
  603. 15800         /* Optimize common case of delete at end of line. */
  604. 15801         End--;
  605. 15802         p = &Line[Point];
  606. 15803         i = 1;
  607. 15804         TTYput(' ');
  608. 15805         if (ISCTL(*p)) {
  609. 15806             i = 2;
  610. 15807             TTYput(' ');
  611. 15808         }
  612. 15809         else if (rl_meta_chars && ISMETA(*p)) {
  613. 15810             i = 3;
  614. 15811             TTYput(' ');
  615. 15812             TTYput(' ');
  616. 15813         }
  617. 15814         TTYbackn(i);
  618. 15815         *p = '';
  619. 15816         return CSmove;
  620. 15817     }
  621. 15818     if (Point + count > End && (count = End - Point) <= 0)
  622. 15819         return CSstay;
  623. 15820
  624. 15821     if (count > 1)
  625. 15822         save_yank(Point, count);
  626. 15823
  627. 15824     for (p = &Line[Point], i = End - (Point + count) + 1; --i >= 0; p++)
  628. 15825         p[0] = p[count];
  629. 15826     ceol();
  630. 15827     End -= count;
  631. 15828     TTYstring(&Line[Point]);
  632. 15829     return CSmove;
  633. 15830 }
  634. 15832 STATIC STATUS
  635. 15833 bk_char()
  636. 15834 {
  637. 15835     int         i;
  638. 15836
  639. 15837     i = 0;
  640. 15838     do {
  641. 15839         if (Point == 0)
  642. 15840             break;
  643. 15841         left(CSmove);
  644. 15842     } while (++i < Repeat);
  645. 15843
  646. 15844     return CSstay;
  647. 15845 }
  648. 15847 STATIC STATUS
  649. 15848 bk_del_char()
  650. 15849 {
  651. 15850     int         i;
  652. 15851
  653. 15852     i = 0;
  654. 15853     do {
  655. 15854         if (Point == 0)
  656. 15855             break;
  657. 15856         left(CSmove);
  658. 15857     } while (++i < Repeat);
  659. 15858
  660. 15859     return delete_string(i);
  661. 15860 }
  662. 15862 STATIC STATUS
  663. 15863 kill_line()
  664. 15864 {
  665. 15865     int         i;
  666. 15866
  667. 15867     if (Repeat != NO_ARG) {
  668. 15868         if (Repeat < Point) {
  669. 15869             i = Point;
  670. 15870             Point = Repeat;
  671. 15871             reposition();
  672. 15872             (void)delete_string(i - Point);
  673. 15873         }
  674. 15874         else if (Repeat > Point) {
  675. 15875             right(CSmove);
  676. 15876             (void)delete_string(Repeat - Point - 1);
  677. 15877         }
  678. 15878         return CSmove;
  679. 15879     }
  680. 15880
  681. 15881     save_yank(Point, End - Point);
  682. 15882     Line[Point] = '';
  683. 15883     ceol();
  684. 15884     End = Point;
  685. 15885     return CSstay;
  686. 15886 }
  687. 15888 STATIC STATUS
  688. 15889 insert_char(c)
  689. 15890     int         c;
  690. 15891 {
  691. 15892     STATUS      s;
  692. 15893     CHAR        buff[2];
  693. 15894     CHAR        *p;
  694. 15895     CHAR        *q;
  695. 15896     int         i;
  696. 15897
  697. 15898     if (Repeat == NO_ARG || Repeat < 2) {
  698. 15899         buff[0] = c;
  699. 15900         buff[1] = '';
  700. 15901         return insert_string(buff);
  701. 15902     }
  702. 15903
  703. 15904     if ((p = NEW(CHAR, Repeat + 1)) == NULL)
  704. 15905         return CSstay;
  705. 15906     for (i = Repeat, q = p; --i >= 0; )
  706. 15907         *q++ = c;
  707. 15908     *q = '';
  708. 15909     Repeat = 0;
  709. 15910     s = insert_string(p);
  710. 15911     DISPOSE(p);
  711. 15912     return s;
  712. 15913 }
  713. 15915 STATIC STATUS
  714. 15916 meta()
  715. 15917 {
  716. 15918     unsigned int        c;
  717. 15919     KEYMAP              *kp;
  718. 15920
  719. 15921     if ((c = TTYget()) == EOF)
  720. 15922         return CSeof;
  721. 15923 #if     defined(ANSI_ARROWS)
  722. 15924     /* Also include VT-100 arrows. */
  723. 15925     if (c == '[' || c == 'O')
  724. 15926         switch (c = TTYget()) {
  725. 15927         default:        return ring_bell();
  726. 15928         case EOF:       return CSeof;
  727. 15929         case 'A':       return h_prev();
  728. 15930         case 'B':       return h_next();
  729. 15931         case 'C':       return fd_char();
  730. 15932         case 'D':       return bk_char();
  731. 15933         }
  732. 15934 #endif  /* defined(ANSI_ARROWS) */
  733. 15935
  734. 15936     if (isdigit(c)) {
  735. 15937         for (Repeat = c - '0'; (c = TTYget()) != EOF && isdigit(c); )
  736. 15938             Repeat = Repeat * 10 + c - '0';
  737. 15939         Pushed = 1;
  738. 15940         PushBack = c;
  739. 15941         return CSstay;
  740. 15942     }
  741. 15943
  742. 15944     if (isupper(c))
  743. 15945         return do_macro(c);
  744. 15946     for (kp = MetaMap; kp->Function; kp++)
  745. 15947         if (kp->Key == c)
  746. 15948             return (*kp->Function)();
  747. 15949
  748. 15950     return ring_bell();
  749. 15951 }
  750. 15953 STATIC STATUS
  751. 15954 emacs(c)
  752. 15955     unsigned int        c;
  753. 15956 {
  754. 15957     STATUS              s;
  755. 15958     KEYMAP              *kp;
  756. 15959
  757. 15960     OldPoint = Point;
  758. 15961     if (rl_meta_chars && ISMETA(c)) {
  759. 15962         Pushed = 1;
  760. 15963         PushBack = UNMETA(c);
  761. 15964         return meta();
  762. 15965     }
  763. 15966     for (kp = Map; kp->Function; kp++)
  764. 15967         if (kp->Key == c)
  765. 15968             break;
  766. 15969     s = kp->Function ? (*kp->Function)() : insert_char((int)c);
  767. 15970     if (!Pushed)
  768. 15971         /* No pushback means no repeat count; hacky, but true. */
  769. 15972         Repeat = NO_ARG;
  770. 15973     return s;
  771. 15974 }
  772. 15976 STATIC STATUS
  773. 15977 TTYspecial(c)
  774. 15978     unsigned int        c;
  775. 15979 {
  776. 15980     if (ISMETA(c))
  777. 15981         return CSdispatch;
  778. 15982
  779. 15983     if (c == rl_erase || c == DEL)
  780. 15984         return bk_del_char();
  781. 15985     if (c == rl_kill) {
  782. 15986         if (Point != 0) {
  783. 15987             Point = 0;
  784. 15988             reposition();
  785. 15989         }
  786. 15990         Repeat = NO_ARG;
  787. 15991         return kill_line();
  788. 15992     }
  789. 15993     if (c == rl_eof && Point == 0 && End == 0)
  790. 15994         return CSeof;
  791. 15995     if (c == rl_intr) {
  792. 15996         Signal = SIGINT;
  793. 15997         return CSsignal;
  794. 15998     }
  795. 15999     if (c == rl_quit) {
  796. 16000         Signal = SIGQUIT;
  797. 16001         return CSeof;
  798. 16002     }
  799. 16003
  800. 16004     return CSdispatch;
  801. 16005 }
  802. 16007 STATIC CHAR *
  803. 16008 editinput()
  804. 16009 {
  805. 16010     unsigned int        c;
  806. 16011
  807. 16012     Repeat = NO_ARG;
  808. 16013     OldPoint = Point = Mark = End = 0;
  809. 16014     Line[0] = '';
  810. 16015
  811. 16016     Signal = -1;
  812. 16017     while ((c = TTYget()) != EOF)
  813. 16018         switch (TTYspecial(c)) {
  814. 16019         case CSdone:
  815. 16020             return Line;
  816. 16021         case CSeof:
  817. 16022             return NULL;
  818. 16023         case CSsignal:
  819. 16024             return (CHAR *)"";
  820. 16025         case CSmove:
  821. 16026             reposition();
  822. 16027             break;
  823. 16028         case CSdispatch:
  824. 16029             switch (emacs(c)) {
  825. 16030             case CSdone:
  826. 16031                 return Line;
  827. 16032             case CSeof:
  828. 16033                 return NULL;
  829. 16034             case CSsignal:
  830. 16035                 return (CHAR *)"";
  831. 16036             case CSmove:
  832. 16037                 reposition();
  833. 16038                 break;
  834. 16039             case CSdispatch:
  835. 16040             case CSstay:
  836. 16041                 break;
  837. 16042             }
  838. 16043             break;
  839. 16044         case CSstay:
  840. 16045             break;
  841. 16046         }
  842. 16047     return NULL;
  843. 16048 }
  844. 16050 STATIC void
  845. 16051 hist_add(p)
  846. 16052     CHAR        *p;
  847. 16053 {
  848. 16054     int         i;
  849. 16055
  850. 16056     if ((p = (CHAR *)strdup((char *)p)) == NULL)
  851. 16057         return;
  852. 16058     if (H.Size < HIST_SIZE)
  853. 16059         H.Lines[H.Size++] = p;
  854. 16060     else {
  855. 16061         DISPOSE(H.Lines[0]);
  856. 16062         for (i = 0; i < HIST_SIZE - 1; i++)
  857. 16063             H.Lines[i] = H.Lines[i + 1];
  858. 16064         H.Lines[i] = p;
  859. 16065     }
  860. 16066     H.Pos = H.Size - 1;
  861. 16067 }
  862. 16069 /*
  863. 16070 **  For compatibility with FSF readline.
  864. 16071 */
  865. 16072 /* ARGSUSED0 */
  866. 16073 void
  867. 16074 rl_reset_terminal(p)
  868. 16075     char        *p;
  869. 16076 {
  870. 16077 }
  871. 16079 void
  872. 16080 rl_initialize()
  873. 16081 {
  874. 16082 }
  875. 16084 char *
  876. 16085 readline(prompt)
  877. 16086     CONST char  *prompt;
  878. 16087 {
  879. 16088     CHAR        *line;
  880. 16089     int         s;
  881. 16090
  882. 16091     if (Line == NULL) {
  883. 16092         Length = MEM_INC;
  884. 16093         if ((Line = NEW(CHAR, Length)) == NULL)
  885. 16094             return NULL;
  886. 16095     }
  887. 16096
  888. 16097     TTYinfo();
  889. 16098     rl_ttyset(0);
  890. 16099     hist_add(NIL);
  891. 16100     ScreenSize = SCREEN_INC;
  892. 16101     Screen = NEW(char, ScreenSize);
  893. 16102     Prompt = prompt ? prompt : (char *)NIL;
  894. 16103     TTYputs((CONST CHAR *)Prompt);
  895. 16104     if ((line = editinput()) != NULL) {
  896. 16105         line = (CHAR *)strdup((char *)line);
  897. 16106         TTYputs((CHAR *)NEWLINE);
  898. 16107         TTYflush();
  899. 16108     }
  900. 16109     rl_ttyset(1);
  901. 16110     DISPOSE(Screen);
  902. 16111     DISPOSE(H.Lines[--H.Size]);
  903. 16112     if (Signal > 0) {
  904. 16113         s = Signal;
  905. 16114         Signal = 0;
  906. 16115         (void)kill(getpid(), s);
  907. 16116     }
  908. 16117     return (char *)line;
  909. 16118 }
  910. 16120 void
  911. 16121 add_history(p)
  912. 16122     char        *p;
  913. 16123 {
  914. 16124     if (p == NULL || *p == '')
  915. 16125         return;
  916. 16126
  917. 16127 #if     defined(UNIQUE_HISTORY)
  918. 16128     if (H.Pos && strcmp(p, (char *) H.Lines[H.Pos - 1]) == 0)
  919. 16129         return;
  920. 16130 #endif  /* defined(UNIQUE_HISTORY) */
  921. 16131     if (H.Size && strcmp(p, (char *) H.Lines[H.Size - 1]) == 0)
  922. 16132         return;
  923. 16133     hist_add((CHAR *)p);
  924. 16134 }
  925. 16135
  926. 16136
  927. 16137 STATIC STATUS
  928. 16138 beg_line()
  929. 16139 {
  930. 16140     if (Point) {
  931. 16141         Point = 0;
  932. 16142         return CSmove;
  933. 16143     }
  934. 16144     return CSstay;
  935. 16145 }
  936. 16147 STATIC STATUS
  937. 16148 del_char()
  938. 16149 {
  939. 16150     return delete_string(Repeat == NO_ARG ? 1 : Repeat);
  940. 16151 }
  941. 16153 STATIC STATUS
  942. 16154 end_line()
  943. 16155 {
  944. 16156     if (Point != End) {
  945. 16157         Point = End;
  946. 16158         return CSmove;
  947. 16159     }
  948. 16160     return CSstay;
  949. 16161 }
  950. 16163 /*
  951. 16164 **  Move back to the beginning of the current word and return an
  952. 16165 **  allocated copy of it.
  953. 16166 */
  954. 16167 STATIC CHAR *
  955. 16168 find_word()
  956. 16169 {
  957. 16170     static char SEPS[] = "#:;&|^$=`'{}()<>nt ";
  958. 16171     CHAR        *p;
  959. 16172     CHAR        *new;
  960. 16173     SIZE_T      len;
  961. 16174
  962. 16175     for (p = &Line[Point]; p > Line && strchr(SEPS, (char)p[-1]) == NULL; p--)
  963. 16176         continue;
  964. 16177     len = Point - (p - Line) + 1;
  965. 16178     if ((new = NEW(CHAR, len)) == NULL)
  966. 16179         return NULL;
  967. 16180     COPYFROMTO(new, p, len);
  968. 16181     new[len - 1] = '';
  969. 16182     return new;
  970. 16183 }
  971. 16185 STATIC STATUS
  972. 16186 c_possible()
  973. 16187 {
  974. 16188     CHAR        **av;
  975. 16189     CHAR        *word;
  976. 16190     int         ac;
  977. 16191
  978. 16192     word = find_word();
  979. 16193     ac = rl_list_possib((char *)word, (char ***)&av);
  980. 16194     if (word)
  981. 16195         DISPOSE(word);
  982. 16196     if (ac) {
  983. 16197         columns(ac, av);
  984. 16198         while (--ac >= 0)
  985. 16199             DISPOSE(av[ac]);
  986. 16200         DISPOSE(av);
  987. 16201         return CSmove;
  988. 16202     }
  989. 16203     return ring_bell();
  990. 16204 }
  991. 16206 STATIC STATUS
  992. 16207 c_complete()
  993. 16208 {
  994. 16209     CHAR        *p;
  995. 16210     CHAR        *word;
  996. 16211     int         unique;
  997. 16212     STATUS      s;
  998. 16213
  999. 16214     word = find_word();
  1000. 16215     p = (CHAR *)rl_complete((char *)word, &unique);
  1001. 16216     if (word)
  1002. 16217         DISPOSE(word);
  1003. 16218     if (p && *p) {
  1004. 16219         s = insert_string(p);
  1005. 16220 #if ANNOYING_NOISE
  1006. 16221         if (!unique)
  1007. 16222             (void)ring_bell();
  1008. 16223 #endif
  1009. 16224         DISPOSE(p);
  1010. 16225         return s;
  1011. 16226     }
  1012. 16227     return c_possible();
  1013. 16228 }
  1014. 16230 STATIC STATUS
  1015. 16231 accept_line()
  1016. 16232 {
  1017. 16233     Line[End] = '';
  1018. 16234     return CSdone;
  1019. 16235 }
  1020. 16237 STATIC STATUS
  1021. 16238 transpose()
  1022. 16239 {
  1023. 16240     CHAR        c;
  1024. 16241
  1025. 16242     if (Point) {
  1026. 16243         if (Point == End)
  1027. 16244             left(CSmove);
  1028. 16245         c = Line[Point - 1];
  1029. 16246         left(CSstay);
  1030. 16247         Line[Point - 1] = Line[Point];
  1031. 16248         TTYshow(Line[Point - 1]);
  1032. 16249         Line[Point++] = c;
  1033. 16250         TTYshow(c);
  1034. 16251     }
  1035. 16252     return CSstay;
  1036. 16253 }
  1037. 16255 STATIC STATUS
  1038. 16256 quote()
  1039. 16257 {
  1040. 16258     unsigned int        c;
  1041. 16259
  1042. 16260     return (c = TTYget()) == EOF ? CSeof : insert_char((int)c);
  1043. 16261 }
  1044. 16263 STATIC STATUS
  1045. 16264 wipe()
  1046. 16265 {
  1047. 16266     int         i;
  1048. 16267
  1049. 16268     if (Mark > End)
  1050. 16269         return ring_bell();
  1051. 16270
  1052. 16271     if (Point > Mark) {
  1053. 16272         i = Point;
  1054. 16273         Point = Mark;
  1055. 16274         Mark = i;
  1056. 16275         reposition();
  1057. 16276     }
  1058. 16277
  1059. 16278     return delete_string(Mark - Point);
  1060. 16279 }
  1061. 16281 STATIC STATUS
  1062. 16282 mk_set()
  1063. 16283 {
  1064. 16284     Mark = Point;
  1065. 16285     return CSstay;
  1066. 16286 }
  1067. 16288 STATIC STATUS
  1068. 16289 exchange()
  1069. 16290 {
  1070. 16291     unsigned int        c;
  1071. 16292
  1072. 16293     if ((c = TTYget()) != CTL('X'))
  1073. 16294         return c == EOF ? CSeof : ring_bell();
  1074. 16295
  1075. 16296     if ((c = Mark) <= End) {
  1076. 16297         Mark = Point;
  1077. 16298         Point = c;
  1078. 16299         return CSmove;
  1079. 16300     }
  1080. 16301     return CSstay;
  1081. 16302 }
  1082. 16304 STATIC STATUS
  1083. 16305 yank()
  1084. 16306 {
  1085. 16307     if (Yanked && *Yanked)
  1086. 16308         return insert_string(Yanked);
  1087. 16309     return CSstay;
  1088. 16310 }
  1089. 16312 STATIC STATUS
  1090. 16313 copy_region()
  1091. 16314 {
  1092. 16315     if (Mark > End)
  1093. 16316         return ring_bell();
  1094. 16317
  1095. 16318     if (Point > Mark)
  1096. 16319         save_yank(Mark, Point - Mark);
  1097. 16320     else
  1098. 16321         save_yank(Point, Mark - Point);
  1099. 16322
  1100. 16323     return CSstay;
  1101. 16324 }
  1102. 16326 STATIC STATUS
  1103. 16327 move_to_char()
  1104. 16328 {
  1105. 16329     unsigned int        c;
  1106. 16330     int                 i;
  1107. 16331     CHAR                *p;
  1108. 16332
  1109. 16333     if ((c = TTYget()) == EOF)
  1110. 16334         return CSeof;
  1111. 16335     for (i = Point + 1, p = &Line[i]; i < End; i++, p++)
  1112. 16336         if (*p == c) {
  1113. 16337             Point = i;
  1114. 16338             return CSmove;
  1115. 16339         }
  1116. 16340     return CSstay;
  1117. 16341 }
  1118. 16343 STATIC STATUS
  1119. 16344 fd_word()
  1120. 16345 {
  1121. 16346     return do_forward(CSmove);
  1122. 16347 }
  1123. 16349 STATIC STATUS
  1124. 16350 fd_kill_word()
  1125. 16351 {
  1126. 16352     int         i;
  1127. 16353
  1128. 16354     (void)do_forward(CSstay);
  1129. 16355     if (OldPoint != Point) {
  1130. 16356         i = Point - OldPoint;
  1131. 16357         Point = OldPoint;
  1132. 16358         return delete_string(i);
  1133. 16359     }
  1134. 16360     return CSstay;
  1135. 16361 }
  1136. 16363 STATIC STATUS
  1137. 16364 bk_word()
  1138. 16365 {
  1139. 16366     int         i;
  1140. 16367     CHAR        *p;
  1141. 16368
  1142. 16369     i = 0;
  1143. 16370     do {
  1144. 16371         for (p = &Line[Point]; p > Line && !isalnum(p[-1]); p--)
  1145. 16372             left(CSmove);
  1146. 16373
  1147. 16374         for (; p > Line && p[-1] != ' ' && isalnum(p[-1]); p--)
  1148. 16375             left(CSmove);
  1149. 16376
  1150. 16377         if (Point == 0)
  1151. 16378             break;
  1152. 16379     } while (++i < Repeat);
  1153. 16380
  1154. 16381     return CSstay;
  1155. 16382 }
  1156. 16384 STATIC STATUS
  1157. 16385 bk_kill_word()
  1158. 16386 {
  1159. 16387     (void)bk_word();
  1160. 16388     if (OldPoint != Point)
  1161. 16389         return delete_string(OldPoint - Point);
  1162. 16390     return CSstay;
  1163. 16391 }
  1164. 16393 STATIC int
  1165. 16394 argify(line, avp)
  1166. 16395     CHAR        *line;
  1167. 16396     CHAR        ***avp;
  1168. 16397 {
  1169. 16398     CHAR        *c;
  1170. 16399     CHAR        **p;
  1171. 16400     CHAR        **new;
  1172. 16401     int         ac;
  1173. 16402     int         i;
  1174. 16403
  1175. 16404     i = MEM_INC;
  1176. 16405     if ((*avp = p = NEW(CHAR*, i))== NULL)
  1177. 16406          return 0;
  1178. 16407
  1179. 16408     for (c = line; isspace(*c); c++)
  1180. 16409         continue;
  1181. 16410     if (*c == 'n' || *c == '')
  1182. 16411         return 0;
  1183. 16412
  1184. 16413     for (ac = 0, p[ac++] = c; *c && *c != 'n'; ) {
  1185. 16414         if (isspace(*c)) {
  1186. 16415             *c++ = '';
  1187. 16416             if (*c && *c != 'n') {
  1188. 16417                 if (ac + 1 == i) {
  1189. 16418                     new = NEW(CHAR*, i + MEM_INC);
  1190. 16419                     if (new == NULL) {
  1191. 16420                         p[ac] = NULL;
  1192. 16421                         return ac;
  1193. 16422                     }
  1194. 16423                     COPYFROMTO(new, p, i * sizeof (char **));
  1195. 16424                     i += MEM_INC;
  1196. 16425                     DISPOSE(p);
  1197. 16426                     *avp = p = new;
  1198. 16427                 }
  1199. 16428                 p[ac++] = c;
  1200. 16429             }
  1201. 16430         }
  1202. 16431         else
  1203. 16432             c++;
  1204. 16433     }
  1205. 16434     *c = '';
  1206. 16435     p[ac] = NULL;
  1207. 16436     return ac;
  1208. 16437 }
  1209. 16439 STATIC STATUS
  1210. 16440 last_argument()
  1211. 16441 {
  1212. 16442     CHAR        **av;
  1213. 16443     CHAR        *p;
  1214. 16444     STATUS      s;
  1215. 16445     int         ac;
  1216. 16446
  1217. 16447     if (H.Size == 1 || (p = H.Lines[H.Size - 2]) == NULL)
  1218. 16448         return ring_bell();
  1219. 16449
  1220. 16450     if ((p = (CHAR *)strdup((char *)p)) == NULL)
  1221. 16451         return CSstay;
  1222. 16452     ac = argify(p, &av);
  1223. 16453
  1224. 16454     if (Repeat != NO_ARG)
  1225. 16455         s = Repeat < ac ? insert_string(av[Repeat]) : ring_bell();
  1226. 16456     else
  1227. 16457         s = ac ? insert_string(av[ac - 1]) : CSstay;
  1228. 16458
  1229. 16459     if (ac)
  1230. 16460         DISPOSE(av);
  1231. 16461     DISPOSE(p);
  1232. 16462     return s;
  1233. 16463 }
  1234. 16465 STATIC KEYMAP   Map[33] = {
  1235. 16466     {   CTL('@'),       mk_set          },
  1236. 16467     {   CTL('A'),       beg_line        },
  1237. 16468     {   CTL('B'),       bk_char         },
  1238. 16469     {   CTL('D'),       del_char        },
  1239. 16470     {   CTL('E'),       end_line        },
  1240. 16471     {   CTL('F'),       fd_char         },
  1241. 16472     {   CTL('G'),       ring_bell       },
  1242. 16473     {   CTL('H'),       bk_del_char     },
  1243. 16474     {   CTL('I'),       c_complete      },
  1244. 16475     {   CTL('J'),       accept_line     },
  1245. 16476     {   CTL('K'),       kill_line       },
  1246. 16477     {   CTL('L'),       redisplay       },
  1247. 16478     {   CTL('M'),       accept_line     },
  1248. 16479     {   CTL('N'),       h_next          },
  1249. 16480     {   CTL('O'),       ring_bell       },
  1250. 16481     {   CTL('P'),       h_prev          },
  1251. 16482     {   CTL('Q'),       ring_bell       },
  1252. 16483     {   CTL('R'),       h_search        },
  1253. 16484     {   CTL('S'),       ring_bell       },
  1254. 16485     {   CTL('T'),       transpose       },
  1255. 16486     {   CTL('U'),       ring_bell       },
  1256. 16487     {   CTL('V'),       quote           },
  1257. 16488     {   CTL('W'),       bk_kill_word    },
  1258. 16489     {   CTL('X'),       exchange        },
  1259. 16490     {   CTL('Y'),       yank            },
  1260. 16491     {   CTL('Z'),       end_line        },
  1261. 16492     {   CTL('['),       meta            },
  1262. 16493     {   CTL(']'),       move_to_char    },
  1263. 16494     {   CTL('^'),       ring_bell       },
  1264. 16495     {   CTL('_'),       ring_bell       },
  1265. 16496     {   0,              NULL            }
  1266. 16497 };
  1267. 16498
  1268. 16499 STATIC KEYMAP   MetaMap[17]= {
  1269. 16500     {   CTL('H'),       wipe            },
  1270. 16501     {   DEL,            wipe            },
  1271. 16502     {   ' ',            mk_set          },
  1272. 16503     {   '.',            last_argument   },
  1273. 16504     {   '<',            h_first         },
  1274. 16505     {   '>',            h_last          },
  1275. 16506     {   '?',            c_possible      },
  1276. 16507     {   'b',            bk_word         },
  1277. 16508     {   'd',            fd_kill_word    },
  1278. 16509     {   'f',            fd_word         },
  1279. 16510     {   'l',            case_down_word  },
  1280. 16511     {   'm',            toggle_meta_mode },
  1281. 16512     {   'u',            case_up_word    },
  1282. 16513     {   'y',            yank            },
  1283. 16514     {   'w',            copy_region     },
  1284. 16515     {   0,              NULL            }
  1285. 16516 };
  1286. ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  1287. src/lib/editline/sysos9.c    
  1288. ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  1289. 16600 /*  $Revision: 1.1 $
  1290. 16601 **
  1291. 16602 **  OS-9 system-dependant routines for editline library.
  1292. 16603 */
  1293. 16604 #include "editline.h"
  1294. 16605 #include <sgstat.h>
  1295. 16606 #include <modes.h>
  1296. 16607
  1297. 16608
  1298. 16609 void
  1299. 16610 rl_ttyset(Reset)
  1300. 16611     int                 Reset;
  1301. 16612 {
  1302. 16613     static struct sgbuf old;
  1303. 16614     struct sgbuf        new;
  1304. 16615
  1305. 16616
  1306. 16617     if (Reset == 0) {
  1307. 16618         _gs_opt(0, &old);
  1308. 16619         _gs_opt(0, &new);
  1309. 16620         new.sg_backsp = 0;      new.sg_delete = 0;      new.sg_echo = 0;
  1310. 16621         new.sg_alf = 0;         new.sg_nulls = 0;       new.sg_pause = 0;
  1311. 16622         new.sg_page = 0;        new.sg_bspch = 0;       new.sg_dlnch = 0;
  1312. 16623         new.sg_eorch = 0;       new.sg_eofch = 0;       new.sg_rlnch = 0;
  1313. 16624         new.sg_dulnch = 0;      new.sg_psch = 0;        new.sg_kbich = 0;
  1314. 16625         new.sg_kbach = 0;       new.sg_bsech = 0;       new.sg_bellch = 0;
  1315. 16626         new.sg_xon = 0;         new.sg_xoff = 0;        new.sg_tabcr = 0;
  1316. 16627         new.sg_tabsiz = 0;
  1317. 16628         _ss_opt(0, &new);
  1318. 16629         rl_erase = old.sg_bspch;
  1319. 16630         rl_kill = old.sg_dlnch;
  1320. 16631         rl_eof = old.sg_eofch;
  1321. 16632         rl_intr = old.sg_kbich;
  1322. 16633         rl_quit = -1;
  1323. 16634     }
  1324. 16635     else
  1325. 16636         _ss_opt(0, &old);
  1326. 16637 }
  1327. 16639 void
  1328. 16640 rl_add_slash(path, p)
  1329. 16641     char        *path;
  1330. 16642     char        *p;
  1331. 16643 {
  1332. 16644     (void)strcat(p, access(path, S_IREAD | S_IFDIR) ? " " : "/");
  1333. 16645 }
  1334. ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  1335. src/lib/editline/sysunix.c    
  1336. ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  1337. 16700 /*  $Revision: 1.2 $
  1338. 16701 **
  1339. 16702 **  Unix system-dependant routines for editline library.
  1340. 16703 */
  1341. 16704 #include "editline.h"
  1342. 16705
  1343. 16706 #if     defined(HAVE_TCGETATTR)
  1344. 16707 #include <termios.h>
  1345. 16708
  1346. 16709 void
  1347. 16710 rl_ttyset(Reset)
  1348. 16711     int                         Reset;
  1349. 16712 {
  1350. 16713     static struct termios       old;
  1351. 16714     struct termios              new;
  1352. 16715
  1353. 16716     if (Reset == 0) {
  1354. 16717         (void)tcgetattr(0, &old);
  1355. 16718         rl_erase = old.c_cc[VERASE];
  1356. 16719         rl_kill = old.c_cc[VKILL];
  1357. 16720         rl_eof = old.c_cc[VEOF];
  1358. 16721         rl_intr = old.c_cc[VINTR];
  1359. 16722         rl_quit = old.c_cc[VQUIT];
  1360. 16723
  1361. 16724         new = old;
  1362. 16725         new.c_lflag &= ~(ECHO | ICANON | ISIG | IEXTEN);
  1363. 16726         new.c_cc[VMIN] = 1;
  1364. 16727         new.c_cc[VTIME] = 0;
  1365. 16728         (void)tcsetattr(0, TCSADRAIN, &new);
  1366. 16729     }
  1367. 16730     else
  1368. 16731         (void)tcsetattr(0, TCSADRAIN, &old);
  1369. 16732 }
  1370. 16734 #else
  1371. 16735 #if     defined(HAVE_TERMIO)
  1372. 16736 #include <termio.h>
  1373. 16737
  1374. 16738 void
  1375. 16739 rl_ttyset(Reset)
  1376. 16740     int                         Reset;
  1377. 16741 {
  1378. 16742     static struct termio        old;
  1379. 16743     struct termio               new;
  1380. 16744
  1381. 16745     if (Reset == 0) {
  1382. 16746         (void)ioctl(0, TCGETA, &old);
  1383. 16747         rl_erase = old.c_cc[VERASE];
  1384. 16748         rl_kill = old.c_cc[VKILL];
  1385. 16749         rl_eof = old.c_cc[VEOF];
  1386. 16750         rl_intr = old.c_cc[VINTR];
  1387. 16751         rl_quit = old.c_cc[VQUIT];
  1388. 16752
  1389. 16753         new = old;
  1390. 16754         new.c_cc[VINTR] = -1;
  1391. 16755         new.c_cc[VQUIT] = -1;
  1392. 16756         new.c_lflag &= ~(ECHO | ICANON);
  1393. 16757         new.c_cc[VMIN] = 1;
  1394. 16758         new.c_cc[VTIME] = 0;
  1395. 16759         (void)ioctl(0, TCSETAW, &new);
  1396. 16760     }
  1397. 16761     else
  1398. 16762         (void)ioctl(0, TCSETAW, &old);
  1399. 16763 }
  1400. 16765 #else
  1401. 16766 #include <sgtty.h>
  1402. 16767
  1403. 16768 void
  1404. 16769 rl_ttyset(Reset)
  1405. 16770     int                         Reset;
  1406. 16771 {
  1407. 16772     static struct sgttyb        old_sgttyb;
  1408. 16773     static struct tchars        old_tchars;
  1409. 16774     struct sgttyb               new_sgttyb;
  1410. 16775     struct tchars               new_tchars;
  1411. 16776
  1412. 16777     if (Reset == 0) {
  1413. 16778         (void)ioctl(0, TIOCGETP, &old_sgttyb);
  1414. 16779         rl_erase = old_sgttyb.sg_erase;
  1415. 16780         rl_kill = old_sgttyb.sg_kill;
  1416. 16781
  1417. 16782         (void)ioctl(0, TIOCGETC, &old_tchars);
  1418. 16783         rl_eof = old_tchars.t_eofc;
  1419. 16784         rl_intr = old_tchars.t_intrc;
  1420. 16785         rl_quit = old_tchars.t_quitc;
  1421. 16786
  1422. 16787         new_sgttyb = old_sgttyb;
  1423. 16788         new_sgttyb.sg_flags &= ~ECHO;
  1424. 16789         new_sgttyb.sg_flags |= RAW;
  1425. 16790         (void)ioctl(0, TIOCSETP, &new_sgttyb);
  1426. 16791
  1427. 16792         new_tchars = old_tchars;
  1428. 16793         new_tchars.t_intrc = -1;
  1429. 16794         new_tchars.t_quitc = -1;
  1430. 16795         (void)ioctl(0, TIOCSETC, &new_tchars);
  1431. 16796     }
  1432. 16797     else {
  1433. 16798         (void)ioctl(0, TIOCSETP, &old_sgttyb);
  1434. 16799         (void)ioctl(0, TIOCSETC, &old_tchars);
  1435. 16800     }
  1436. 16801 }
  1437. 16802 #endif  /* defined(HAVE_TERMIO) */
  1438. 16803 #endif  /* defined(HAVE_TCGETATTR) */
  1439. 16804
  1440. 16805 void
  1441. 16806 rl_add_slash(path, p)
  1442. 16807     char        *path;
  1443. 16808     char        *p;
  1444. 16809 {
  1445. 16810     struct stat Sb;
  1446. 16811
  1447. 16812     if (stat(path, &Sb) >= 0)
  1448. 16813         (void)strcat(p, S_ISDIR(Sb.st_mode) ? "/" : " ");
  1449. 16814 }
  1450. ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  1451. src/lib/editline/testit.c    
  1452. ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  1453. 16900 /*  $Revision: 1.3 $
  1454. 16901 **
  1455. 16902 **  A "micro-shell" to test editline library.
  1456. 16903 **  If given any arguments, commands aren't executed.
  1457. 16904 */
  1458. 16905 #include <stdio.h>
  1459. 16906 #if     defined(HAVE_STDLIB)
  1460. 16907 #include <stdlib.h>
  1461. 16908 #endif  /* defined(HAVE_STDLIB) */
  1462. 16909
  1463. 16910 extern char     *readline();
  1464. 16911 extern void     add_history();
  1465. 16912
  1466. 16913 #if     !defined(HAVE_STDLIB)
  1467. 16914 extern int      chdir();
  1468. 16915 extern int      free();
  1469. 16916 extern int      strncmp();
  1470. 16917 extern int      system();
  1471. 16918 extern void     exit();
  1472. 16919 extern char     *getenv();
  1473. 16920 #endif  /* !defined(HAVE_STDLIB) */
  1474. 16921
  1475. 16922
  1476. 16923 #if     defined(NEED_PERROR)
  1477. 16924 void
  1478. 16925 perror(s)
  1479. 16926     char        *s;
  1480. 16927 {
  1481. 16928     extern int  errno;
  1482. 16929
  1483. 16930     (voidf)printf(stderr, "%s: error %dn", s, errno);
  1484. 16931 }
  1485. 16932 #endif  /* defined(NEED_PERROR) */
  1486. 16933
  1487. 16934
  1488. 16935 /* ARGSUSED1 */
  1489. 16936 int
  1490. 16937 main(ac, av)
  1491. 16938     int         ac;
  1492. 16939     char        *av[];
  1493. 16940 {
  1494. 16941     char        *prompt;
  1495. 16942     char        *p;
  1496. 16943     int         doit;
  1497. 16944
  1498. 16945     doit = ac == 1;
  1499. 16946     if ((prompt = getenv("TESTPROMPT")) == NULL)
  1500. 16947         prompt = "testit>  ";
  1501. 16948
  1502. 16949     while ((p = readline(prompt)) != NULL) {
  1503. 16950         (void)printf("ttt|%s|n", p);
  1504. 16951         if (doit)
  1505. 16952             if (strncmp(p, "cd ", 3) == 0) {
  1506. 16953                 if (chdir(&p[3]) < 0)
  1507. 16954                     perror(&p[3]);
  1508. 16955             }
  1509. 16956             else if (system(p) != 0)
  1510. 16957                 perror(p);
  1511. 16958         add_history(p);
  1512. 16959         free(p);
  1513. 16960     }
  1514. 16961     exit(0);
  1515. 16962     /* NOTREACHED */
  1516. 16963 }
  1517. ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  1518. src/lib/end/edata.s    
  1519. ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  1520. 17000 #
  1521. 17001 .sect .text
  1522. 17002 .sect .rom
  1523. 17003 .sect .data
  1524. 17004 .sect .bss
  1525. 17005 .define _edata
  1526. 17006 .sect .data
  1527. 17007         .align _EM_WSIZE
  1528. 17008 _edata:
  1529. ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  1530. src/lib/end/em_end.s    
  1531. ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  1532. 17100 #
  1533. 17101 .sect .text
  1534. 17102 .sect .rom
  1535. 17103 .sect .data
  1536. 17104 .sect .bss
  1537. 17105 .define endtext,enddata,endbss,__end
  1538. 17106 .sect .text
  1539. 17107         .align _EM_WSIZE
  1540. 17108 .sect .rom
  1541. 17109         .align _EM_WSIZE
  1542. 17110 .sect .data
  1543. 17111         .align _EM_WSIZE
  1544. 17112 .sect .bss
  1545. 17113         .align _EM_WSIZE
  1546. 17114 .sect .end ! only for declaration of _end, __end and endbss.
  1547. 17115
  1548. 17116         .sect .text
  1549. 17117 endtext:
  1550. 17118         .sect .rom
  1551. 17119 endrom:
  1552. 17120         .sect .data
  1553. 17121 enddata:
  1554. 17122         .sect .end
  1555. 17123 __end:
  1556. 17124 endbss:
  1557. ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  1558. src/lib/end/end.s    
  1559. ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  1560. 17200 .sect .text
  1561. 17201 .sect .rom
  1562. 17202 .sect .data
  1563. 17203 .sect .bss
  1564. 17204 .define _end
  1565. 17205 .sect .end ! only for declaration of _end, __end and endbss.
  1566. 17206 _end:
  1567. ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  1568. src/lib/end/etext.s    
  1569. ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  1570. 17300 #
  1571. 17301 .sect .text
  1572. 17302 .sect .rom
  1573. 17303 .sect .data
  1574. 17304 .sect .bss
  1575. 17305 .define _etext
  1576. 17306 .sect .text
  1577. 17307         .align _EM_WSIZE
  1578. 17308         .sect .text
  1579. 17309 _etext:
  1580. ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  1581. src/lib/float/FP_bias.h    
  1582. ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  1583. 17400 /*
  1584. 17401   (c) copyright 1988 by the Vrije Universiteit, Amsterdam, The Netherlands.
  1585. 17402   See the copyright notice in the ACK home directory, in the file "Copyright".
  1586. 17403 */
  1587. 17404
  1588. 17405 /* $Header: FP_bias.h,v 1.4 89/07/25 14:16:55 ceriel Exp $ */
  1589. 17406
  1590. 17407 /*
  1591. 17408         include file for floating point package
  1592. 17409 */
  1593. 17410
  1594. 17411                 /*      FLOAT FORMAT EXPONENT BIAS      */
  1595. 17412
  1596. 17413 #define SGL_BIAS         127    /* excess  128 notation used    */
  1597. 17414 #define DBL_BIAS        1023    /* excess 1024 notation used    */
  1598. 17415 #define EXT_BIAS           0    /* 2s-complement notation used  */
  1599. 17416                                 /* this is possible because the */
  1600. 17417                                 /* sign is in a seperate word   */
  1601. 17418                 
  1602. 17419                 /*      VARIOUS MAX AND MIN VALUES      */
  1603. 17420                 /*      1) FOR THE DIFFERENT FORMATS    */
  1604. 17421
  1605. 17422 #define SGL_MAX            254  /*      standard definition     */
  1606. 17423 #define SGL_MIN              1  /*      standard definition     */
  1607. 17424 #define DBL_MAX           2046  /*      standard definition     */
  1608. 17425 #define DBL_MIN              1  /*      standard definition     */
  1609. 17426 #define EXT_MAX          16383  /*      standard minimum        */
  1610. 17427 #define EXT_MIN         -16382  /*      standard minimum        */
  1611. ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  1612. src/lib/float/FP_shift.h    
  1613. ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  1614. 17500 /*
  1615. 17501   (c) copyright 1988 by the Vrije Universiteit, Amsterdam, The Netherlands.
  1616. 17502   See the copyright notice in the ACK home directory, in the file "Copyright".
  1617. 17503 */
  1618. 17504
  1619. 17505 /* $Header: FP_shift.h,v 1.3 89/07/25 14:17:04 ceriel Exp $ */
  1620. 17506
  1621. 17507 /*
  1622. 17508         include file for floating point package
  1623. 17509 */
  1624. 17510
  1625. 17511 # define        CARRYBIT        0x80000000L
  1626. 17512 # define        NORMBIT         0x80000000L
  1627. 17513 # define        EXP_STORE       16
  1628. 17514
  1629. 17515
  1630. 17516                                 /* parameters for Single Precision */
  1631. 17517 #define SGL_EXPSHIFT    7
  1632. 17518 #define SGL_M1LEFT      8
  1633. 17519 #define SGL_ZERO        0xffffff80L
  1634. 17520 #define SGL_EXACT       0xff
  1635. 17521 #define SGL_RUNPACK     SGL_M1LEFT
  1636. 17522
  1637. 17523 #define SGL_ROUNDUP     0x80
  1638. 17524 #define SGL_CARRYOUT    0x01000000L
  1639. 17525 #define SGL_MASK        0x007fffffL
  1640. 17526
  1641. 17527                                 /* parameters for Double Precision */
  1642. 17528                                 /* used in extend.c */
  1643. 17529
  1644. 17530 #define DBL_EXPSHIFT    4
  1645. 17531
  1646. 17532 #define DBL_M1LEFT      11
  1647. 17533
  1648. 17534 #define DBL_RPACK       (32-DBL_M1LEFT)
  1649. 17535 #define DBL_LPACK       DBL_M1LEFT
  1650. 17536
  1651. 17537                                 /* used in compact.c */
  1652. 17538
  1653. 17539 #define DBL_ZERO        0xfffffd00L
  1654. 17540
  1655. 17541 #define DBL_EXACT       0x7ff
  1656. 17542
  1657. 17543 #define DBL_RUNPACK     DBL_M1LEFT
  1658. 17544 #define DBL_LUNPACK     (32-DBL_RUNPACK)
  1659. 17545
  1660. 17546 #define DBL_ROUNDUP     0x400
  1661. 17547 #define DBL_CARRYOUT    0x00200000L
  1662. 17548 #define DBL_MASK        0x000fffffL
  1663. ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  1664. src/lib/float/FP_trap.h    
  1665. ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  1666. 17600 /*
  1667. 17601   (c) copyright 1988 by the Vrije Universiteit, Amsterdam, The Netherlands.
  1668. 17602   See the copyright notice in the ACK home directory, in the file "Copyright".
  1669. 17603 */
  1670. 17604
  1671. 17605 /* $Header: FP_trap.h,v 1.2 88/04/07 11:33:06 ceriel Exp $ */
  1672. 17606
  1673. 17607 /*
  1674. 17608         include file for floating point package
  1675. 17609 */
  1676. 17610
  1677. 17611                         /*      EM TRAPS        */
  1678. 17612
  1679. 17613 #define EIOVFL  3       /* Integer  Overflow            */
  1680. 17614 #define EFOVFL  4       /* Floating Overflow            */
  1681. 17615 #define EFUNFL  5       /* Floating Underflow           */
  1682. 17616 #define EIDIVZ  6       /* Integer  Divide by 0         */
  1683. 17617 #define EFDIVZ  7       /* Floating Divide by 0.0       */
  1684. 17618 #define EIUND   8       /* Integer  Undefined Number    */
  1685. 17619 #define EFUND   9       /* Floating Undefined Number    */
  1686. 17620 #define ECONV   10      /* Conversion Error             */
  1687. 17621 # define trap(x) _fptrp(x)
  1688. ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  1689. src/lib/float/FP_types.h    
  1690. ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  1691. 17700 /*
  1692. 17701   (c) copyright 1988 by the Vrije Universiteit, Amsterdam, The Netherlands.
  1693. 17702   See the copyright notice in the ACK home directory, in the file "Copyright".
  1694. 17703 */
  1695. 17704
  1696. 17705 /* $Header: FP_types.h,v 1.4 93/01/05 12:03:05 ceriel Exp $ */
  1697. 17706
  1698. 17707 /********************************************************/
  1699. 17708 /*
  1700. 17709         Type definitions for C Floating Point Package
  1701. 17710         include file for floating point package
  1702. 17711 */
  1703. 17712 /********************************************************/
  1704. 17713 /*
  1705. 17714         THESE STRUCTURES ARE USED TO ADDRESS THE INDIVIDUAL
  1706. 17715         PARTS OF THE FLOATING POINT NUMBER REPRESENTATIONS.
  1707. 17716
  1708. 17717         THREE STRUCTURES ARE DEFINED:
  1709. 17718                 SINGLE: single precision floating format
  1710. 17719                 DOUBLE: double precision floating format
  1711. 17720                 EXTEND: double precision extended format
  1712. 17721 */
  1713. 17722 /********************************************************/
  1714. 17723
  1715. 17724 #ifndef __FPTYPES
  1716. 17725 #define __FPTYPES
  1717. 17726
  1718. 17727 typedef struct  {
  1719. 17728         unsigned long   h_32;   /* higher 32 bits of 64 */
  1720. 17729         unsigned long   l_32;   /* lower  32 bits of 64 */
  1721. 17730 }       B64;
  1722. 17731
  1723. 17732 typedef unsigned long   SINGLE;
  1724. 17733
  1725. 17734 typedef struct  {
  1726. 17735         unsigned long   d[2];
  1727. 17736 }       DOUBLE;
  1728. 17737
  1729. 17738 typedef struct  {       /* expanded float format        */
  1730. 17739         short   sign;
  1731. 17740         short   exp;
  1732. 17741         B64     mantissa;
  1733. 17742 #define m1 mantissa.h_32
  1734. 17743 #define m2 mantissa.l_32
  1735. 17744 } EXTEND;
  1736. 17745
  1737. 17746 struct  fef4_returns {
  1738. 17747         int     e;
  1739. 17748         SINGLE  f;
  1740. 17749 };
  1741. 17750
  1742. 17751 struct  fef8_returns {
  1743. 17752         int     e;
  1744. 17753         DOUBLE  f;
  1745. 17754 };
  1746. 17755
  1747. 17756 struct fif4_returns {
  1748. 17757         SINGLE ipart;
  1749. 17758         SINGLE fpart;
  1750. 17759 };
  1751. 17760
  1752. 17761 struct fif8_returns {
  1753. 17762         DOUBLE ipart;
  1754. 17763         DOUBLE fpart;
  1755. 17764 };
  1756. 17765
  1757. 17766 #if __STDC__
  1758. 17767 #define _PROTOTYPE(function, params)    function params
  1759. 17768 #else
  1760. 17769 #define _PROTOTYPE(function, params)    function()
  1761. 17770 #endif
  1762. 17771 _PROTOTYPE( void add_ext, (EXTEND *e1, EXTEND *e2));
  1763. 17772 _PROTOTYPE( void mul_ext, (EXTEND *e1, EXTEND *e2));
  1764. 17773 _PROTOTYPE( void div_ext, (EXTEND *e1, EXTEND *e2));
  1765. 17774 _PROTOTYPE( void sub_ext, (EXTEND *e1, EXTEND *e2));
  1766. 17775 _PROTOTYPE( void sft_ext, (EXTEND *e1, EXTEND *e2));
  1767. 17776 _PROTOTYPE( void nrm_ext, (EXTEND *e1));
  1768. 17777 _PROTOTYPE( void zrf_ext, (EXTEND *e1));
  1769. 17778 _PROTOTYPE( void extend, (unsigned long *from, EXTEND *to, int size));
  1770. 17779 _PROTOTYPE( void compact, (EXTEND *from, unsigned long *to, int size));
  1771. 17780 _PROTOTYPE( void _fptrp, (int));
  1772. 17781 _PROTOTYPE( void adf4, (SINGLE s2, SINGLE s1));
  1773. 17782 _PROTOTYPE( void adf8, (DOUBLE s2, DOUBLE s1));
  1774. 17783 _PROTOTYPE( void sbf4, (SINGLE s2, SINGLE s1));
  1775. 17784 _PROTOTYPE( void sbf8, (DOUBLE s2, DOUBLE s1));
  1776. 17785 _PROTOTYPE( void dvf4, (SINGLE s2, SINGLE s1));
  1777. 17786 _PROTOTYPE( void dvf8, (DOUBLE s2, DOUBLE s1));
  1778. 17787 _PROTOTYPE( void mlf4, (SINGLE s2, SINGLE s1));
  1779. 17788 _PROTOTYPE( void mlf8, (DOUBLE s2, DOUBLE s1));
  1780. 17789 _PROTOTYPE( void ngf4, (SINGLE f));
  1781. 17790 _PROTOTYPE( void ngf8, (DOUBLE f));
  1782. 17791 _PROTOTYPE( void zrf4, (SINGLE *l));
  1783. 17792 _PROTOTYPE( void zrf8, (DOUBLE *z));
  1784. 17793 _PROTOTYPE( void cff4, (DOUBLE src));
  1785. 17794 _PROTOTYPE( void cff8, (SINGLE src));
  1786. 17795 _PROTOTYPE( void cif4, (int ss, long src));
  1787. 17796 _PROTOTYPE( void cif8, (int ss, long src));
  1788. 17797 _PROTOTYPE( void cuf4, (int ss, long src));
  1789. 17798 _PROTOTYPE( void cuf8, (int ss, long src));
  1790. 17799 _PROTOTYPE( long cfu, (int ds, int ss, DOUBLE src));
  1791. 17800 _PROTOTYPE( long cfi, (int ds, int ss, DOUBLE src));
  1792. 17801 _PROTOTYPE( int cmf4, (SINGLE s2, SINGLE s1));
  1793. 17802 _PROTOTYPE( int cmf8, (DOUBLE d1, DOUBLE d2));
  1794. 17803 _PROTOTYPE( void fef4, (struct fef4_returns *r, SINGLE s1));
  1795. 17804 _PROTOTYPE( void fef8, (struct fef8_returns *r, DOUBLE s1));
  1796. 17805 _PROTOTYPE( void fif4, (struct fif4_returns *p, SINGLE x, SINGLE y));
  1797. 17806 _PROTOTYPE( void fif8, (struct fif8_returns *p, DOUBLE x, DOUBLE y));
  1798. 17807
  1799. 17808 _PROTOTYPE( void b64_sft, (B64 *, int));
  1800. 17809 _PROTOTYPE( void b64_lsft, (B64 *));
  1801. 17810 _PROTOTYPE( void b64_rsft, (B64 *));
  1802. 17811 _PROTOTYPE( int b64_add, (B64 *, B64 *));
  1803. 17812 #endif
  1804. ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  1805. src/lib/float/adder.h    
  1806. ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  1807. 17900 /*
  1808. 17901   (c) copyright 1988 by the Vrije Universiteit, Amsterdam, The Netherlands.
  1809. 17902   See the copyright notice in the ACK home directory, in the file "Copyright".
  1810. 17903 */
  1811. 17904
  1812. 17905 /* $Header: adder.h,v 1.2 92/02/20 18:20:25 philip Exp $ */
  1813. 17906
  1814. 17907 /*
  1815. 17908  *      include file for 32 & 64 bit addition
  1816. 17909  */
  1817. 17910
  1818. 17911 typedef struct  B64 {
  1819. 17912         unsigned long   h_32;   /* higher 32 bits of 64 */
  1820. 17913         unsigned long   l_32;   /* lower  32 bits of 64 */
  1821. 17914 }       B64;
  1822. ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  1823. src/lib/float/byte_order.h    
  1824. ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  1825. 18000 #define CHAR_UNSIGNED   0
  1826. 18001 #define MSB_AT_LOW_ADDRESS      0
  1827. 18002 #define MSW_AT_LOW_ADDRESS      0
  1828. 18003 #define FL_MSB_AT_LOW_ADDRESS   0
  1829. 18004 #define FL_MSW_AT_LOW_ADDRESS   0
  1830. 18005 #define FL_MSL_AT_LOW_ADDRESS   0
  1831. ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  1832. src/lib/float/get_put.h    
  1833. ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  1834. 18100 /*
  1835. 18101   (c) copyright 1988 by the Vrije Universiteit, Amsterdam, The Netherlands.
  1836. 18102   See the copyright notice in the ACK home directory, in the file "Copyright".
  1837. 18103 */
  1838. 18104
  1839. 18105 /* $Header: get_put.h,v 1.3 89/10/25 17:15:01 ceriel Exp $ */
  1840. 18106
  1841. 18107 #include <byte_order.h>
  1842. 18108
  1843. 18109 #if CHAR_UNSIGNED
  1844. 18110 #define Xchar(ch)       (ch)
  1845. 18111 #else
  1846. 18112 #define Xchar(ch)       ((ch) & 0377)
  1847. 18113 #endif
  1848. 18114
  1849. 18115 #define BYTES_REVERSED (MSB_AT_LOW_ADDRESS != FL_MSB_AT_LOW_ADDRESS)
  1850. 18116 #define WORDS_REVERSED (MSW_AT_LOW_ADDRESS != FL_MSW_AT_LOW_ADDRESS)
  1851. 18117 #define LONGS_REVERSED (FL_MSL_AT_LOW_ADDRESS)
  1852. 18118
  1853. 18119 #if BYTES_REVERSED
  1854. 18120 #define uget2(c)        (Xchar((c)[1]) | ((unsigned) Xchar((c)[0]) << 8))
  1855. 18121 #define Xput2(i, c)     (((c)[1] = (i)), ((c)[0] = (i) >> 8))
  1856. 18122 #define put2(i, c)      { register int j = (i); Xput2(j, c); }
  1857. 18123 #else
  1858. 18124 #define uget2(c)        (* ((unsigned short *) (c)))
  1859. 18125 #define Xput2(i, c)     (* ((short *) (c)) = (i))
  1860. 18126 #define put2(i, c)      Xput2(i, c)
  1861. 18127 #endif
  1862. 18128
  1863. 18129 #define get2(c)         ((short) uget2(c))
  1864. 18130
  1865. 18131 #if WORDS_REVERSED || BYTES_REVERSED
  1866. 18132 #define get4(c)         (uget2((c)+2) | ((long) uget2(c) << 16))
  1867. 18133 #define put4(l, c)      { register long x=(l); 
  1868. 18134                           Xput2((int)x,(c)+2); 
  1869. 18135                           Xput2((int)(x>>16),(c)); 
  1870. 18136                         }
  1871. 18137 #else
  1872. 18138 #define get4(c)         (* ((long *) (c)))
  1873. 18139 #define put4(l, c)      (* ((long *) (c)) = (l))
  1874. 18140 #endif
  1875. ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  1876. src/lib/float/add_ext.c    
  1877. ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  1878. 18200 /*
  1879. 18201   (c) copyright 1988 by the Vrije Universiteit, Amsterdam, The Netherlands.
  1880. 18202   See the copyright notice in the ACK home directory, in the file "Copyright".
  1881. 18203 */
  1882. 18204
  1883. 18205 /* $Header: add_ext.c,v 1.7 93/01/05 12:03:11 ceriel Exp $ */
  1884. 18206
  1885. 18207 /*
  1886. 18208         ADD TWO EXTENDED FORMAT NUMBERS
  1887. 18209 */
  1888. 18210
  1889. 18211 #include "FP_types.h"
  1890. 18212
  1891. 18213 void
  1892. 18214 add_ext(e1,e2)
  1893. 18215 register EXTEND *e1,*e2;
  1894. 18216 {
  1895. 18217         if ((e2->m1 | e2->m2) == 0L) {
  1896. 18218                 return;
  1897. 18219         }
  1898. 18220         if ((e1->m1 | e1->m2) == 0L) {
  1899. 18221                 *e1 = *e2;
  1900. 18222                 return;
  1901. 18223         }
  1902. 18224         sft_ext(e1, e2);        /* adjust mantissas to equal powers */
  1903. 18225         if (e1->sign != e2->sign) {
  1904. 18226                 /* e1 + e2 = e1 - (-e2) */
  1905. 18227                 if (e2->m1 > e1->m1 ||
  1906. 18228                     (e2->m1 == e1->m1 && e2->m2 > e1->m2)) {
  1907. 18229                         /*      abs(e2) > abs(e1) */
  1908. 18230                         EXTEND x;
  1909. 18231
  1910. 18232                         x = *e1;
  1911. 18233                         *e1 = *e2;
  1912. 18234                         if (x.m2 > e1->m2) {
  1913. 18235                                 e1->m1 -= 1;    /* carry in */
  1914. 18236                         }
  1915. 18237                         e1->m1 -= x.m1;
  1916. 18238                         e1->m2 -= x.m2;
  1917. 18239                 }
  1918. 18240                 else {
  1919. 18241                         if (e2->m2 > e1->m2)
  1920. 18242                                 e1->m1 -= 1;    /* carry in */
  1921. 18243                         e1->m1 -= e2->m1;
  1922. 18244                         e1->m2 -= e2->m2;
  1923. 18245                 }
  1924. 18246         }
  1925. 18247         else {
  1926. 18248                 if (b64_add(&e1->mantissa,&e2->mantissa)) {     /* addition carry */
  1927. 18249                         b64_rsft(&e1->mantissa);        /* shift mantissa one bit RIGHT */
  1928. 18250                         e1->m1 |= 0x80000000L;  /* set max bit  */
  1929. 18251                         e1->exp++;              /* increase the exponent */
  1930. 18252                 }
  1931. 18253         }
  1932. 18254         nrm_ext(e1);
  1933. 18255 }
  1934. ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  1935. src/lib/float/adder.c    
  1936. ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  1937. 18300 /*
  1938. 18301   (c) copyright 1988 by the Vrije Universiteit, Amsterdam, The Netherlands.
  1939. 18302   See the copyright notice in the ACK home directory, in the file "Copyright".
  1940. 18303 */
  1941. 18304
  1942. 18305 /* $Header: adder.c,v 1.6 93/01/05 12:03:17 ceriel Exp $ */
  1943. 18306
  1944. 18307 /*
  1945. 18308  *      these are the routines the routines to do 32 and  64-bit addition
  1946. 18309  */
  1947. 18310
  1948. 18311 # ifdef EXT_DEBUG
  1949. 18312 # include <stdio.h>
  1950. 18313 # endif
  1951. 18314
  1952. 18315 # include "FP_types.h"
  1953. 18316 # define        UNKNOWN -1
  1954. 18317 # define        TRUE     1
  1955. 18318 # define        FALSE    0
  1956. 18319 # define        MAXBIT  0x80000000L
  1957. 18320
  1958. 18321         /*
  1959. 18322          *      add 64 bits
  1960. 18323          */
  1961. 18324 int
  1962. 18325 b64_add(e1,e2)
  1963. 18326                 /*
  1964. 18327                  * pointers to 64 bit 'registers'
  1965. 18328                  */
  1966. 18329 register        B64     *e1,*e2;
  1967. 18330 {
  1968. 18331                 register        int     overflow;
  1969. 18332                                 int     carry;
  1970. 18333
  1971. 18334                         /* add higher pair of 32 bits */
  1972. 18335         overflow = ((unsigned long) 0xFFFFFFFF - e1->h_32 < e2->h_32);
  1973. 18336         e1->h_32 += e2->h_32;
  1974. 18337
  1975. 18338                         /* add lower pair of 32 bits */
  1976. 18339         carry = ((unsigned long) 0xFFFFFFFF - e1->l_32 < e2->l_32);
  1977. 18340         e1->l_32 += e2->l_32;
  1978. 18341 # ifdef EXT_DEBUG
  1979. 18342         printf("tttttb64_add: overflow (%d); internal carry(%d)n",
  1980. 18343                                         overflow,carry);
  1981. 18344         fflush(stdout);
  1982. 18345 # endif
  1983. 18346         if ((carry) && (++e1->h_32 == 0))
  1984. 18347                 return(TRUE);           /* had a 64 bit overflow */
  1985. 18348         return(overflow);               /* return status from higher add */
  1986. 18349 }
  1987. ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  1988. src/lib/float/adf4.c    
  1989. ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  1990. 18400 /*
  1991. 18401   (c) copyright 1988 by the Vrije Universiteit, Amsterdam, The Netherlands.
  1992. 18402   See the copyright notice in the ACK home directory, in the file "Copyright".
  1993. 18403 */
  1994. 18404
  1995. 18405 /* $Header: adf4.c,v 1.7 93/01/05 12:03:23 ceriel Exp $ */
  1996. 18406
  1997. 18407 /*
  1998. 18408         ADD TWO FLOATS - SINGLE (ADF 4)
  1999. 18409 */
  2000. 18410
  2001. 18411 #include        "FP_types.h"
  2002. 18412
  2003. 18413 void
  2004. 18414 adf4(s2,s1)
  2005. 18415 SINGLE  s1,s2;
  2006. 18416 {
  2007. 18417         EXTEND  e1,e2;
  2008. 18418         int     swap = 0;
  2009. 18419
  2010. 18420         if (s1 == (SINGLE) 0) {
  2011. 18421                 s1 = s2;
  2012. 18422                 return;
  2013. 18423         }
  2014. 18424         if (s2 == (SINGLE) 0) {
  2015. 18425                 return;
  2016. 18426         }
  2017. 18427         extend(&s1,&e1,sizeof(SINGLE));
  2018. 18428         extend(&s2,&e2,sizeof(SINGLE));
  2019. 18429         add_ext(&e1,&e2);
  2020. 18430         compact(&e1,&s1,sizeof(SINGLE));
  2021. 18431 }
  2022. ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  2023. src/lib/float/adf8.c    
  2024. ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  2025. 18500 /*
  2026. 18501   (c) copyright 1988 by the Vrije Universiteit, Amsterdam, The Netherlands.
  2027. 18502   See the copyright notice in the ACK home directory, in the file "Copyright".
  2028. 18503 */
  2029. 18504
  2030. 18505 /* $Header: adf8.c,v 1.7 93/01/05 12:03:29 ceriel Exp $ */
  2031. 18506
  2032. 18507 /*
  2033. 18508         ADD TWO FLOATS - DOUBLE (ADF 8)
  2034. 18509 */
  2035. 18510
  2036. 18511 #include        "FP_types.h"
  2037. 18512
  2038. 18513 void
  2039. 18514 adf8(s2,s1)
  2040. 18515 DOUBLE  s1,s2;
  2041. 18516 {
  2042. 18517         EXTEND  e1,e2;
  2043. 18518
  2044. 18519         if (s1.d[0] == 0 && s1.d[1] == 0) {
  2045. 18520                 s1 = s2;
  2046. 18521                 return;
  2047. 18522         }
  2048. 18523         if (s2.d[0] == 0 && s2.d[1] == 0) {
  2049. 18524                 return;
  2050. 18525         }
  2051. 18526
  2052. 18527         extend(&s1.d[0],&e1,sizeof(DOUBLE));
  2053. 18528         extend(&s2.d[0],&e2,sizeof(DOUBLE));
  2054. 18529         add_ext(&e1,&e2);
  2055. 18530         compact(&e1,&s1.d[0],sizeof(DOUBLE));
  2056. 18531 }
  2057. ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  2058. src/lib/float/cff4.c    
  2059. ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  2060. 18600 /*
  2061. 18601   (c) copyright 1988 by the Vrije Universiteit, Amsterdam, The Netherlands.
  2062. 18602   See the copyright notice in the ACK home directory, in the file "Copyright".
  2063. 18603 */
  2064. 18604
  2065. 18605 /* $Header: cff4.c,v 1.5 93/01/05 12:03:36 ceriel Exp $ */
  2066. 18606
  2067. 18607 /*
  2068. 18608                 CONVERT DOUBLE TO SINGLE (CFF 8 4)
  2069. 18609
  2070. 18610         This routine works quite simply. A floating point
  2071. 18611         of size 08 is converted to extended format.
  2072. 18612         This extended variable is converted back to
  2073. 18613         a floating point of size 04.
  2074. 18614
  2075. 18615 */
  2076. 18616
  2077. 18617 #include        "FP_types.h"
  2078. 18618
  2079. 18619 void
  2080. 18620 cff4(src)
  2081. 18621 DOUBLE  src;    /* the source itself -  THIS TIME it's DOUBLE */
  2082. 18622 {
  2083. 18623         EXTEND  buf;
  2084. 18624
  2085. 18625         extend(&src.d[0],&buf,sizeof(DOUBLE));  /* no matter what */
  2086. 18626         compact(&buf,&(src.d[1]),sizeof(SINGLE));
  2087. 18627 }
  2088. ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  2089. src/lib/float/cff8.c    
  2090. ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  2091. 18700 /*
  2092. 18701   (c) copyright 1988 by the Vrije Universiteit, Amsterdam, The Netherlands.
  2093. 18702   See the copyright notice in the ACK home directory, in the file "Copyright".
  2094. 18703 */
  2095. 18704
  2096. 18705 /* $Header: cff8.c,v 1.5 93/01/05 12:03:41 ceriel Exp $ */
  2097. 18706
  2098. 18707 /*
  2099. 18708                 CONVERT SINGLE TO DOUBLE (CFF 4 8)
  2100. 18709
  2101. 18710         This routine works quite simply. A floating point
  2102. 18711         of size 04 is converted to extended format.
  2103. 18712         This extended variable is converted back to
  2104. 18713         a floating point of size 08.
  2105. 18714
  2106. 18715 */
  2107. 18716
  2108. 18717 #include "FP_types.h"
  2109. 18718
  2110. 18719 void
  2111. 18720 cff8(src)
  2112. 18721 SINGLE  src;
  2113. 18722 {
  2114. 18723         EXTEND  buf;
  2115. 18724
  2116. 18725         extend(&src,&buf,sizeof(SINGLE));       /* no matter what */
  2117. 18726         compact(&buf, &src,sizeof(DOUBLE));
  2118. 18727 }
  2119. ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  2120. src/lib/float/cfi.c    
  2121. ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  2122. 18800 /*
  2123. 18801   (c) copyright 1988 by the Vrije Universiteit, Amsterdam, The Netherlands.
  2124. 18802   See the copyright notice in the ACK home directory, in the file "Copyright".
  2125. 18803 */
  2126. 18804
  2127. 18805 /* $Header: cfi.c,v 1.5 93/01/05 12:03:48 ceriel Exp $ */
  2128. 18806
  2129. 18807 /*
  2130. 18808                 CONVERT FLOAT TO SIGNED (CFI m n)
  2131. 18809
  2132. 18810                 N.B. The caller must know what it is getting.
  2133. 18811                      A LONG is always returned. If it is an
  2134. 18812                      integer the high byte is cleared first.
  2135. 18813 */
  2136. 18814
  2137. 18815 #include "FP_trap.h"
  2138. 18816 #include "FP_types.h"
  2139. 18817 #include "FP_shift.h"
  2140. 18818
  2141. 18819 long
  2142. 18820 cfi(ds,ss,src)
  2143. 18821 int     ds;     /* destination size (2 or 4) */
  2144. 18822 int     ss;     /* source size      (4 or 8) */
  2145. 18823 DOUBLE  src;    /* assume worst case */
  2146. 18824 {
  2147. 18825         EXTEND  buf;
  2148. 18826         long    new;
  2149. 18827         short   max_exp;
  2150. 18828
  2151. 18829         extend(&src.d[0],&buf,ss);      /* get extended format */
  2152. 18830         if (buf.exp < 0) {      /* no conversion needed */
  2153. 18831                 src.d[ss == 8] = 0L;
  2154. 18832                 return(0L);
  2155. 18833         }
  2156. 18834         max_exp = (ds << 3) - 2;        /* signed numbers */
  2157. 18835                                 /* have more limited max_exp */
  2158. 18836         if (buf.exp > max_exp) {
  2159. 18837                 if (buf.exp == max_exp+1 && buf.sign && buf.m1 == NORMBIT &&
  2160. 18838                     buf.m2 == 0L) {
  2161. 18839                 }
  2162. 18840                 else {
  2163. 18841                         trap(EIOVFL);   /* integer overflow     */
  2164. 18842                         buf.exp %= max_exp; /* truncate */
  2165. 18843                 }
  2166. 18844         }
  2167. 18845         new = buf.m1 >> (31-buf.exp);
  2168. 18846         if (buf.sign)
  2169. 18847                 new = -new;
  2170. 18848 done:
  2171. 18849         src.d[ss == 8] = new;
  2172. 18850         return(new);
  2173. 18851 }
  2174. ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  2175. src/lib/float/cfu.c    
  2176. ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  2177. 18900 /*
  2178. 18901   (c) copyright 1988 by the Vrije Universiteit, Amsterdam, The Netherlands.
  2179. 18902   See the copyright notice in the ACK home directory, in the file "Copyright".
  2180. 18903 */
  2181. 18904
  2182. 18905 /* $Header: cfu.c,v 1.5 93/01/05 12:03:55 ceriel Exp $ */
  2183. 18906
  2184. 18907 /*
  2185. 18908                 CONVERT FLOAT TO UNSIGNED (CFU m n)
  2186. 18909
  2187. 18910                 N.B. The caller must know what it is getting.
  2188. 18911                      A LONG is always returned. If it is an
  2189. 18912                      integer the high byte is cleared first.
  2190. 18913 */
  2191. 18914
  2192. 18915 #include "FP_trap.h"
  2193. 18916 #include "FP_types.h"
  2194. 18917
  2195. 18918 long
  2196. 18919 cfu(ds,ss,src)
  2197. 18920 int     ds;     /* destination size (2 or 4) */
  2198. 18921 int     ss;     /* source size      (4 or 8) */
  2199. 18922 DOUBLE  src;    /* assume worst case */
  2200. 18923 {
  2201. 18924         EXTEND  buf;
  2202. 18925         long    new;
  2203. 18926         short   newint, max_exp;
  2204. 18927
  2205. 18928         extend(&src.d[0],&buf,ss);      /* get extended format  */
  2206. 18929         if (buf.exp < 0) {      /* no conversion needed */
  2207. 18930                 src.d[ss == 8] = 0L;
  2208. 18931                 return(0L);
  2209. 18932         }
  2210. 18933         max_exp = (ds << 3) - 1;
  2211. 18934         if (buf.exp > max_exp) {
  2212. 18935                 trap(EIOVFL);   /* integer overflow     */
  2213. 18936                 buf.exp %= max_exp;
  2214. 18937         }
  2215. 18938         new = buf.m1 >> (31-buf.exp);
  2216. 18939 done:
  2217. 18940         src.d[ss == 8] = new;
  2218. 18941         return(new);
  2219. 18942 }
  2220. ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  2221. src/lib/float/cif4.c    
  2222. ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  2223. 19000 /*
  2224. 19001   (c) copyright 1988 by the Vrije Universiteit, Amsterdam, The Netherlands.
  2225. 19002   See the copyright notice in the ACK home directory, in the file "Copyright".
  2226. 19003 */
  2227. 19004
  2228. 19005 /* $Header: cif4.c,v 1.5 93/01/05 12:04:01 ceriel Exp $ */
  2229. 19006
  2230. 19007 /*
  2231. 19008         CONVERT INTEGER TO SINGLE (CIF n 4)
  2232. 19009
  2233. 19010         THIS ROUTINE WORKS BY FILLING AN EXTENDED
  2234. 19011         WITH THE INTEGER VALUE IN EXTENDED FORMAT
  2235. 19012         AND USES COMPACT() TO PUT IT INTO THE PROPER
  2236. 19013         FLOATING POINT PRECISION.
  2237. 19014 */
  2238. 19015
  2239. 19016 #include "FP_types.h"
  2240. 19017
  2241. 19018 void
  2242. 19019 cif4(ss,src)
  2243. 19020 int     ss;     /* source size */
  2244. 19021 long    src;    /* largest possible integer to convert */
  2245. 19022 {
  2246. 19023         EXTEND  buf;
  2247. 19024         short   *ipt;
  2248. 19025         long    i_src;
  2249. 19026         SINGLE  *result;
  2250. 19027
  2251. 19028         zrf_ext(&buf);
  2252. 19029         if (ss == sizeof(long)) {
  2253. 19030                 buf.exp = 31;
  2254. 19031                 i_src = src;
  2255. 19032                 result = (SINGLE *) &src;
  2256. 19033         }
  2257. 19034         else    {
  2258. 19035                 ipt = (short *) &src;
  2259. 19036                 i_src = (long) *ipt;
  2260. 19037                 buf.exp = 15;
  2261. 19038                 result = (SINGLE *) &ss;
  2262. 19039         }
  2263. 19040         if (i_src == 0) {
  2264. 19041                 *result = (SINGLE) 0L;
  2265. 19042                 return;
  2266. 19043         }
  2267. 19044                         /* ESTABLISHED THAT src != 0    */
  2268. 19045                         /* adjust exponent field        */
  2269. 19046         buf.sign = (i_src < 0) ? 0x8000 : 0;
  2270. 19047                         /* clear sign bit of integer    */
  2271. 19048                         /* move to mantissa field       */
  2272. 19049         buf.m1 = (i_src < 0) ? -i_src : i_src;
  2273. 19050                         /* adjust mantissa field        */
  2274. 19051         if (ss != sizeof(long))
  2275. 19052                 buf.m1 <<= 16;
  2276. 19053         nrm_ext(&buf);          /* adjust mantissa field        */
  2277. 19054         compact(&buf, result,sizeof(SINGLE));   /* put on stack */
  2278. 19055 }
  2279. ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  2280. src/lib/float/cif8.c    
  2281. ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  2282. 19100 /*
  2283. 19101   (c) copyright 1988 by the Vrije Universiteit, Amsterdam, The Netherlands.
  2284. 19102   See the copyright notice in the ACK home directory, in the file "Copyright".
  2285. 19103 */
  2286. 19104
  2287. 19105 /* $Header: cif8.c,v 1.5 93/01/05 12:04:07 ceriel Exp $ */
  2288. 19106
  2289. 19107 /*
  2290. 19108         CONVERT INTEGER TO FLOAT (CIF n 8)
  2291. 19109
  2292. 19110         THIS ROUTINE WORKS BY FILLING AN EXTENDED
  2293. 19111         WITH THE INTEGER VALUE IN EXTENDED FORMAT
  2294. 19112         AND USES COMPACT() TO PUT IT INTO THE PROPER
  2295. 19113         FLOATING POINT PRECISION.
  2296. 19114 */
  2297. 19115
  2298. 19116 #include "FP_types.h"
  2299. 19117
  2300. 19118 void
  2301. 19119 cif8(ss,src)
  2302. 19120 int     ss;     /* source size */
  2303. 19121 long    src;    /* largest possible integer to convert */
  2304. 19122 {
  2305. 19123         EXTEND  buf;
  2306. 19124         DOUBLE  *result;        /* for return value */
  2307. 19125         short   *ipt;
  2308. 19126         long    i_src;
  2309. 19127
  2310. 19128         result = (DOUBLE *) ((void *) &ss);     /* always */
  2311. 19129         zrf_ext(&buf);
  2312. 19130         if (ss == sizeof(long)) {
  2313. 19131                 buf.exp = 31;
  2314. 19132                 i_src = src;
  2315. 19133         }
  2316. 19134         else    {
  2317. 19135                 ipt = (short *) &src;
  2318. 19136                 i_src = (long) *ipt;
  2319. 19137                 buf.exp = 15;
  2320. 19138         }
  2321. 19139         if (i_src == 0) {
  2322. 19140                 zrf8(result);
  2323. 19141                 return;
  2324. 19142         }
  2325. 19143                         /* ESTABLISHED THAT src != 0    */
  2326. 19144                         /* adjust exponent field        */
  2327. 19145         buf.sign = (i_src < 0) ? 0x8000 : 0;
  2328. 19146                         /* clear sign bit of integer    */
  2329. 19147                         /* move to mantissa field       */
  2330. 19148         buf.m1 = (i_src < 0) ? -i_src : i_src;
  2331. 19149                         /* adjust mantissa field        */
  2332. 19150         if (ss != sizeof(long))
  2333. 19151                 buf.m1 <<= 16;
  2334. 19152         nrm_ext(&buf);
  2335. 19153         compact(&buf,&result->d[0],8);
  2336. 19154 }
  2337. ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  2338. src/lib/float/cmf4.c    
  2339. ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  2340. 19200 /*
  2341. 19201   (c) copyright 1988 by the Vrije Universiteit, Amsterdam, The Netherlands.
  2342. 19202   See the copyright notice in the ACK home directory, in the file "Copyright".
  2343. 19203 */
  2344. 19204
  2345. 19205 /* $Header: cmf4.c,v 1.6 93/01/05 12:04:14 ceriel Exp $ */
  2346. 19206
  2347. 19207 /*
  2348. 19208         COMPARE SINGLES (CMF 4)
  2349. 19209 */
  2350. 19210
  2351. 19211 #include        "FP_types.h"
  2352. 19212 #include        "get_put.h"
  2353. 19213
  2354. 19214 int
  2355. 19215 cmf4(f1,f2)
  2356. 19216 SINGLE  f1,f2;
  2357. 19217 {
  2358. 19218                 /*
  2359. 19219                  * return ((f1 < f2) ? 1 : (f1 - f2))
  2360. 19220                  */
  2361. 19221 #define SIGN(x) (((x) < 0) ? -1 : 1)
  2362. 19222         int     sign1,sign2;
  2363. 19223         long    l1,l2;
  2364. 19224
  2365. 19225         l1 = get4((char *) &f1);
  2366. 19226         l2 = get4((char *) &f2);
  2367. 19227
  2368. 19228         if (l1 == l2) return 0;
  2369. 19229
  2370. 19230         sign1 = SIGN(l1);
  2371. 19231         sign2 = SIGN(l2);
  2372. 19232         if (sign1 != sign2) {
  2373. 19233                 if ((l1 & 0x7fffffff) == 0 &&
  2374. 19234                     (l2 & 0x7fffffff) == 0) return 0;
  2375. 19235                 return ((sign1 > 0) ? -1 : 1);
  2376. 19236         }
  2377. 19237
  2378. 19238         return (sign1 * ((l1 < l2) ? 1 : -1));
  2379. 19239 }
  2380. ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  2381. src/lib/float/cmf8.c    
  2382. ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  2383. 19300 /*
  2384. 19301   (c) copyright 1988 by the Vrije Universiteit, Amsterdam, The Netherlands.
  2385. 19302   See the copyright notice in the ACK home directory, in the file "Copyright".
  2386. 19303 */
  2387. 19304
  2388. 19305 /* $Header: cmf8.c,v 1.9 93/01/05 12:04:22 ceriel Exp $ */
  2389. 19306
  2390. 19307 /*
  2391. 19308         COMPARE DOUBLES (CMF 8)
  2392. 19309 */
  2393. 19310
  2394. 19311 #include        "FP_types.h"
  2395. 19312 #include        "get_put.h"
  2396. 19313
  2397. 19314 int
  2398. 19315 cmf8(d1,d2)
  2399. 19316 DOUBLE  d1,d2;
  2400. 19317 {
  2401. 19318 #define SIGN(x) (((x) < 0) ? -1 : 1)
  2402. 19319                 /*
  2403. 19320                  * return ((d1 < d2) ? 1 : (d1 > d2) ? -1 : 0))
  2404. 19321                  */
  2405. 19322         long    l1,l2;
  2406. 19323         int     sign1,sign2;
  2407. 19324         int     rv;
  2408. 19325
  2409. 19326 #if FL_MSL_AT_LOW_ADDRESS
  2410. 19327         l1 = get4((char *)&d1);
  2411. 19328         l2 = get4((char *)&d2);
  2412. 19329 #else
  2413. 19330         l1 = get4(((char *)&d1+4));
  2414. 19331         l2 = get4(((char *)&d2+4));
  2415. 19332 #endif
  2416. 19333         sign1 = SIGN(l1);
  2417. 19334         sign2 = SIGN(l2);
  2418. 19335         if (sign1 != sign2) {
  2419. 19336                 l1 &= 0x7fffffff;
  2420. 19337                 l2 &= 0x7fffffff;
  2421. 19338                 if (l1 != 0 || l2 != 0) {
  2422. 19339                         return ((sign1 > 0) ? -1 : 1);
  2423. 19340                 }
  2424. 19341         }
  2425. 19342         if (l1 != l2)   {       /* we can decide here */
  2426. 19343                 rv = l1 < l2 ? 1 : -1;
  2427. 19344         }
  2428. 19345         else    {               /* decide in 2nd half */
  2429. 19346                 unsigned long u1, u2;
  2430. 19347 #if FL_MSL_AT_LOW_ADDRESS
  2431. 19348                 u1 = get4(((char *)&d1 + 4));
  2432. 19349                 u2 = get4(((char *)&d2 + 4));
  2433. 19350 #else
  2434. 19351                 u1 = get4((char *)&d1);
  2435. 19352                 u2 = get4((char *)&d2);
  2436. 19353 #endif
  2437. 19354                 if (u1 == u2)
  2438. 19355                         return(0);
  2439. 19356                 if (u1 < u2) rv = 1;
  2440. 19357                 else rv = -1;
  2441. 19358         }
  2442. 19359         return sign1 * rv;
  2443. 19360 }
  2444. ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  2445. src/lib/float/compact.c    
  2446. ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  2447. 19400 /*
  2448. 19401   (c) copyright 1988 by the Vrije Universiteit, Amsterdam, The Netherlands.
  2449. 19402   See the copyright notice in the ACK home directory, in the file "Copyright".
  2450. 19403 */
  2451. 19404
  2452. 19405 /* $Header: compact.c,v 1.13 93/01/05 12:04:28 ceriel Exp $ */
  2453. 19406
  2454. 19407 /*
  2455. 19408         COMPACT EXTEND FORMAT INTO FLOAT OF PROPER SIZE
  2456. 19409 */
  2457. 19410
  2458. 19411 # include "FP_bias.h"
  2459. 19412 # include "FP_shift.h"
  2460. 19413 # include "FP_trap.h"
  2461. 19414 # include "FP_types.h"
  2462. 19415 # include "get_put.h"
  2463. 19416
  2464. 19417 void
  2465. 19418 compact(f,to,size)
  2466. 19419 EXTEND  *f;
  2467. 19420 unsigned long   *to;
  2468. 19421 int     size;
  2469. 19422 {
  2470. 19423         int     error = 0;
  2471. 19424
  2472. 19425         if (size == sizeof(DOUBLE)) {
  2473. 19426         /*
  2474. 19427          * COMPACT EXTENDED INTO DOUBLE
  2475. 19428          */
  2476. 19429                 DOUBLE *DBL = (DOUBLE *) (void *) to;
  2477. 19430
  2478. 19431                 if ((f->m1|(f->m2 & DBL_ZERO)) == 0L)   {
  2479. 19432                         zrf8(DBL);
  2480. 19433                         return;
  2481. 19434                 }
  2482. 19435                 f->exp += DBL_BIAS;     /* restore proper bias  */
  2483. 19436                 if (f->exp > DBL_MAX)   {
  2484. 19437 dbl_over:                       trap(EFOVFL);
  2485. 19438                         f->exp = DBL_MAX+1;
  2486. 19439                         f->m1 = 0;
  2487. 19440                         f->m2 = 0;
  2488. 19441                         if (error++)
  2489. 19442                                 return;
  2490. 19443                 }
  2491. 19444                 else if (f->exp < DBL_MIN)      {
  2492. 19445                         b64_rsft(&(f->mantissa));
  2493. 19446                         if (f->exp < 0) {
  2494. 19447                                 b64_sft(&(f->mantissa), -f->exp);
  2495. 19448                                 f->exp = 0;
  2496. 19449                         }
  2497. 19450                         /* underflow ??? */
  2498. 19451                 }
  2499. 19452                         
  2500. 19453                 /* local CAST conversion                */
  2501. 19454
  2502. 19455                 /* because of special format shift only 10 bits */
  2503. 19456                 /* bit shift mantissa 10 bits           */
  2504. 19457
  2505. 19458                 /* first align within words, then do store operation */
  2506. 19459
  2507. 19460                 DBL->d[0] = f->m1 >> DBL_RUNPACK;   /* plus 22 == 32 */
  2508. 19461                 DBL->d[1] = f->m2 >> DBL_RUNPACK;   /* plus 22 == 32 */
  2509. 19462                 DBL->d[1] |= (f->m1 << DBL_LUNPACK); /* plus 10 == 32 */
  2510. 19463
  2511. 19464                 /* if not exact then round to nearest   */
  2512. 19465                 /* on a tie, round to even */
  2513. 19466
  2514. 19467 #ifdef EXCEPTION_INEXACT
  2515. 19468                 if ((f->m2 & DBL_EXACT) != 0) {
  2516. 19469                     INEXACT();
  2517. 19470 #endif
  2518. 19471                     if (((f->m2 & DBL_EXACT) > DBL_ROUNDUP)
  2519. 19472                         || ((f->m2 & DBL_EXACT) == DBL_ROUNDUP
  2520. 19473                             && (f->m2 & (DBL_ROUNDUP << 1)))) {
  2521. 19474                         DBL->d[1]++;    /* rounding up  */
  2522. 19475                         if (DBL->d[1] == 0L) { /* carry out     */
  2523. 19476                             DBL->d[0]++;
  2524. 19477
  2525. 19478                             if (f->exp == 0 && (DBL->d[0] & ~DBL_MASK)) {
  2526. 19479                                         f->exp++;
  2527. 19480                                 }
  2528. 19481                             if (DBL->d[0] & DBL_CARRYOUT) { /* carry out */
  2529. 19482                                 if (DBL->d[0] & 01)
  2530. 19483                                     DBL->d[1] = CARRYBIT;
  2531. 19484                                 DBL->d[0] >>= 1;
  2532. 19485                                 f->exp++;
  2533. 19486                             }
  2534. 19487                         }
  2535. 19488                         /*      check for overflow                      */
  2536. 19489                         if (f->exp > DBL_MAX)
  2537. 19490                                 goto dbl_over;
  2538. 19491                     }
  2539. 19492 #ifdef EXCEPTION_INEXACT
  2540. 19493                 }
  2541. 19494 #endif
  2542. 19495
  2543. 19496                 /*
  2544. 19497                  * STORE EXPONENT AND SIGN:
  2545. 19498                  *
  2546. 19499                  * 1) clear leading bits (B4-B15)
  2547. 19500                  * 2) shift and store exponent
  2548. 19501                  */
  2549. 19502
  2550. 19503                 DBL->d[0] &= DBL_MASK;
  2551. 19504                 DBL->d[0] |= 
  2552. 19505                         ((long) (f->exp << DBL_EXPSHIFT) << EXP_STORE);
  2553. 19506                 if (f->sign)
  2554. 19507                         DBL->d[0] |= CARRYBIT;
  2555. 19508
  2556. 19509                 /*
  2557. 19510                  * STORE MANTISSA
  2558. 19511                  */
  2559. 19512
  2560. 19513 #if FL_MSL_AT_LOW_ADDRESS
  2561. 19514                 put4(DBL->d[0], (char *) &DBL->d[0]);
  2562. 19515                 put4(DBL->d[1], (char *) &DBL->d[1]);
  2563. 19516 #else
  2564. 19517                 { unsigned long l;
  2565. 19518                   put4(DBL->d[1], (char *) &l);
  2566. 19519                   put4(DBL->d[0], (char *) &DBL->d[1]);
  2567. 19520                   DBL->d[0] = l;
  2568. 19521                 }
  2569. 19522 #endif
  2570. 19523         }
  2571. 19524         else {
  2572. 19525                 /*
  2573. 19526                  * COMPACT EXTENDED INTO FLOAT
  2574. 19527                  */
  2575. 19528                 SINGLE  *SGL;
  2576. 19529
  2577. 19530                 /* local CAST conversion                */
  2578. 19531                 SGL = (SINGLE *) (void *) to;
  2579. 19532                 if ((f->m1 & SGL_ZERO) == 0L)   {
  2580. 19533                         *SGL = 0L;
  2581. 19534                         return;
  2582. 19535                 }
  2583. 19536                 f->exp += SGL_BIAS;     /* restore bias */
  2584. 19537                 if (f->exp > SGL_MAX)   {
  2585. 19538 sgl_over:                       trap(EFOVFL);
  2586. 19539                         f->exp = SGL_MAX+1;
  2587. 19540                         f->m1 = 0L;
  2588. 19541                         f->m2 = 0L;
  2589. 19542                         if (error++)
  2590. 19543                                 return;
  2591. 19544                 }
  2592. 19545                 else if (f->exp < SGL_MIN)      {
  2593. 19546                         b64_rsft(&(f->mantissa));
  2594. 19547                         if (f->exp < 0) {
  2595. 19548                                 b64_sft(&(f->mantissa), -f->exp);
  2596. 19549                                 f->exp = 0;
  2597. 19550                         }
  2598. 19551                         /* underflow ??? */
  2599. 19552                 }
  2600. 19553
  2601. 19554                 /* shift mantissa and store     */
  2602. 19555                 *SGL = (f->m1 >> SGL_RUNPACK);
  2603. 19556
  2604. 19557                 /* check for rounding to nearest        */
  2605. 19558                 /* on a tie, round to even              */
  2606. 19559 #ifdef EXCEPTION_INEXACT
  2607. 19560                 if (f->m2 != 0 ||
  2608. 19561                     (f->m1 & SGL_EXACT) != 0L) {
  2609. 19562                         INEXACT();
  2610. 19563 #endif
  2611. 19564                         if (((f->m1 & SGL_EXACT) > SGL_ROUNDUP)
  2612. 19565                             || ((f->m1 & SGL_EXACT) == SGL_ROUNDUP
  2613. 19566                                 && (f->m1 & (SGL_ROUNDUP << 1)))) {
  2614. 19567                                 (*SGL)++;
  2615. 19568                                 if (f->exp == 0 && (*SGL & ~SGL_MASK)) {
  2616. 19569                                         f->exp++;
  2617. 19570                                 }
  2618. 19571                         /* check normal */
  2619. 19572                                 if (*SGL & SGL_CARRYOUT)        {
  2620. 19573                                         *SGL >>= 1;
  2621. 19574                                         f->exp++;
  2622. 19575                                 }
  2623. 19576                                 if (f->exp > SGL_MAX)
  2624. 19577                                         goto sgl_over;
  2625. 19578                         }
  2626. 19579 #ifdef EXCEPTION_INEXACT
  2627. 19580                 }
  2628. 19581 #endif
  2629. 19582
  2630. 19583                 /*
  2631. 19584                  * STORE EXPONENT AND SIGN:
  2632. 19585                  *
  2633. 19586                  * 1) clear leading bit of fraction
  2634. 19587                  * 2) shift and store exponent
  2635. 19588                  */
  2636. 19589
  2637. 19590                 *SGL &= SGL_MASK; /* B23-B31 are 0 */
  2638. 19591                 *SGL |= ((long) (f->exp << SGL_EXPSHIFT) << EXP_STORE);
  2639. 19592                 if (f->sign)
  2640. 19593                         *SGL |= CARRYBIT;
  2641. 19594
  2642. 19595                 /*
  2643. 19596                  * STORE MANTISSA
  2644. 19597                  */
  2645. 19598
  2646. 19599                 put4(*SGL, (char *) &SGL);
  2647. 19600         }
  2648. 19601 }
  2649. ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  2650. src/lib/float/cuf4.c    
  2651. ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  2652. 19700 /*
  2653. 19701   (c) copyright 1988 by the Vrije Universiteit, Amsterdam, The Netherlands.
  2654. 19702   See the copyright notice in the ACK home directory, in the file "Copyright".
  2655. 19703 */
  2656. 19704
  2657. 19705 /* $Header: cuf4.c,v 1.6 93/01/05 12:04:35 ceriel Exp $ */
  2658. 19706
  2659. 19707 /*
  2660. 19708         CONVERT INTEGER TO SINGLE (CUF n 4)
  2661. 19709
  2662. 19710         THIS ROUTINE WORKS BY FILLING AN EXTENDED
  2663. 19711         WITH THE INTEGER VALUE IN EXTENDED FORMAT
  2664. 19712         AND USES COMPACT() TO PUT IT INTO THE PROPER
  2665. 19713         FLOATING POINT PRECISION.
  2666. 19714 */
  2667. 19715
  2668. 19716 #include "FP_types.h"
  2669. 19717
  2670. 19718 void
  2671. 19719 cuf4(ss,src)
  2672. 19720 int     ss;     /* source size */
  2673. 19721 long    src;    /* largest possible integer to convert */
  2674. 19722 {
  2675. 19723         EXTEND  buf;
  2676. 19724         short   *ipt;
  2677. 19725         SINGLE  *result;
  2678. 19726         long    i_src;
  2679. 19727
  2680. 19728         zrf_ext(&buf);
  2681. 19729         if (ss == sizeof(long)) {
  2682. 19730                 buf.exp = 31;
  2683. 19731                 i_src = src;
  2684. 19732                 result = (SINGLE *) &src;
  2685. 19733         }
  2686. 19734         else    {
  2687. 19735                 ipt = (short *) &src;
  2688. 19736                 i_src = (long) *ipt;
  2689. 19737                 buf.exp = 15;
  2690. 19738                 result = (SINGLE *) ((void *) &ss);
  2691. 19739         }
  2692. 19740         if (i_src == 0) {
  2693. 19741                 *result = (SINGLE) 0L;
  2694. 19742                 return;
  2695. 19743         }
  2696. 19744                         /* ESTABLISHED THAT src != 0    */
  2697. 19745
  2698. 19746                         /* adjust exponent field        */
  2699. 19747         if (ss != sizeof(long))
  2700. 19748                 i_src <<= 16;
  2701. 19749
  2702. 19750                         /* move to mantissa field       */
  2703. 19751         buf.m1 = i_src;
  2704. 19752
  2705. 19753                         /* adjust mantissa field        */
  2706. 19754         nrm_ext(&buf);
  2707. 19755         compact(&buf,result,4);
  2708. 19756 }
  2709. ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  2710. src/lib/float/cuf8.c    
  2711. ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  2712. 19800 /*
  2713. 19801   (c) copyright 1988 by the Vrije Universiteit, Amsterdam, The Netherlands.
  2714. 19802   See the copyright notice in the ACK home directory, in the file "Copyright".
  2715. 19803 */
  2716. 19804
  2717. 19805 /* $Header: cuf8.c,v 1.6 93/01/05 12:04:41 ceriel Exp $ */
  2718. 19806
  2719. 19807 /*
  2720. 19808         CONVERT INTEGER TO FLOAT (CUF n 8)
  2721. 19809
  2722. 19810         THIS ROUTINE WORKS BY FILLING AN EXTENDED
  2723. 19811         WITH THE INTEGER VALUE IN EXTENDED FORMAT
  2724. 19812         AND USES COMPACT() TO PUT IT INTO THE PROPER
  2725. 19813         FLOATING POINT PRECISION.
  2726. 19814 */
  2727. 19815
  2728. 19816 #include "FP_types.h"
  2729. 19817
  2730. 19818 void
  2731. 19819 cuf8(ss,src)
  2732. 19820 int     ss;     /* source size */
  2733. 19821 long    src;    /* largest possible integer to convert */
  2734. 19822 {
  2735. 19823         EXTEND  buf;
  2736. 19824         short   *ipt;
  2737. 19825         long    i_src;
  2738. 19826
  2739. 19827         zrf_ext(&buf);
  2740. 19828         if (ss == sizeof(long)) {
  2741. 19829                 buf.exp = 31;
  2742. 19830                 i_src = src;
  2743. 19831         }
  2744. 19832         else    {
  2745. 19833                 ipt = (short *) &src;
  2746. 19834                 i_src = (long) *ipt;
  2747. 19835                 buf.exp = 15;
  2748. 19836         }
  2749. 19837         if (i_src == 0) {
  2750. 19838                 zrf8((DOUBLE *)((void *)&ss));
  2751. 19839                 return;
  2752. 19840         }
  2753. 19841                         /* ESTABLISHED THAT src != 0    */
  2754. 19842
  2755. 19843                         /* adjust exponent field        */
  2756. 19844         if (ss != sizeof(long))
  2757. 19845                 i_src <<= 16;
  2758. 19846
  2759. 19847                         /* move to mantissa field       */
  2760. 19848         buf.m1 = i_src;
  2761. 19849
  2762. 19850                         /* adjust mantissa field        */
  2763. 19851         nrm_ext(&buf);
  2764. 19852         compact(&buf,(unsigned long *) (void *)&ss,8);
  2765. 19853 }
  2766. ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  2767. src/lib/float/div_ext.c    
  2768. ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  2769. 19900 /*
  2770. 19901   (c) copyright 1988 by the Vrije Universiteit, Amsterdam, The Netherlands.
  2771. 19902   See the copyright notice in the ACK home directory, in the file "Copyright".
  2772. 19903 */
  2773. 19904
  2774. 19905 /* $Header: div_ext.c,v 1.10 93/01/05 12:04:47 ceriel Exp $ */
  2775. 19906
  2776. 19907 /*
  2777. 19908         DIVIDE EXTENDED FORMAT
  2778. 19909 */
  2779. 19910
  2780. 19911 #include "FP_bias.h"
  2781. 19912 #include "FP_trap.h"
  2782. 19913 #include "FP_types.h"
  2783. 19914
  2784. 19915 /*
  2785. 19916         November 15, 1984
  2786. 19917
  2787. 19918         This is a routine to do the work.
  2788. 19919         There are two versions: 
  2789. 19920         One is based on the partial products method
  2790. 19921         and makes no use possible machine instructions
  2791. 19922         to divide (hardware dividers).
  2792. 19923         The other is used when USE_DIVIDE is defined. It is much faster on
  2793. 19924         machines with fast 4 byte operations.
  2794. 19925 */
  2795. 19926 /********************************************************/
  2796. 19927
  2797. 19928 void
  2798. 19929 div_ext(e1,e2)
  2799. 19930 EXTEND  *e1,*e2;
  2800. 19931 {
  2801. 19932         short   error = 0;
  2802. 19933         B64             result;
  2803. 19934         register        unsigned long   *lp;
  2804. 19935 #ifndef USE_DIVIDE
  2805. 19936         short   count;
  2806. 19937 #else
  2807. 19938         unsigned short u[9], v[5];
  2808. 19939         register int j;
  2809. 19940         register unsigned short *u_p = u;
  2810. 19941         int maxv = 4;
  2811. 19942 #endif
  2812. 19943
  2813. 19944         if ((e2->m1 | e2->m2) == 0) {
  2814. 19945                 /*
  2815. 19946                  * Exception 8.2 - Divide by zero
  2816. 19947                  */
  2817. 19948                 trap(EFDIVZ);
  2818. 19949                 e1->m1 = e1->m2 = 0L;
  2819. 19950                 e1->exp = EXT_MAX;
  2820. 19951                 return;
  2821. 19952         }
  2822. 19953         if ((e1->m1 | e1->m2) == 0) {   /* 0 / anything == 0 */
  2823. 19954                 e1->exp = 0;    /* make sure */
  2824. 19955                 return;
  2825. 19956         }
  2826. 19957 #ifndef USE_DIVIDE
  2827. 19958         /*
  2828. 19959          * numbers are right shifted one bit to make sure
  2829. 19960          * that m1 is quaranteed to be larger if its
  2830. 19961          * maximum bit is set
  2831. 19962          */
  2832. 19963         b64_rsft(&e1->mantissa);        /* 64 bit shift right */
  2833. 19964         b64_rsft(&e2->mantissa);        /* 64 bit shift right */
  2834. 19965         e1->exp++;
  2835. 19966         e2->exp++;
  2836. 19967 #endif
  2837. 19968         /*      check for underflow, divide by zero, etc        */
  2838. 19969         e1->sign ^= e2->sign;
  2839. 19970         e1->exp -= e2->exp;
  2840. 19971
  2841. 19972 #ifndef USE_DIVIDE
  2842. 19973                 /* do division of mantissas     */
  2843. 19974                 /* uses partial product method  */
  2844. 19975                 /* init control variables       */
  2845. 19976
  2846. 19977         count = 64;
  2847. 19978         result.h_32 = 0L;
  2848. 19979         result.l_32 = 0L;
  2849. 19980
  2850. 19981                 /* partial product division loop */
  2851. 19982
  2852. 19983         while (count--) {
  2853. 19984                 /* first left shift result 1 bit        */
  2854. 19985                 /* this is ALWAYS done                  */
  2855. 19986
  2856. 19987                 b64_lsft(&result);
  2857. 19988
  2858. 19989                 /* compare dividend and divisor         */
  2859. 19990                 /* if dividend >= divisor add a bit     */
  2860. 19991                 /* and subtract divisior from dividend  */
  2861. 19992
  2862. 19993                 if ( (e1->m1 < e2->m1) ||
  2863. 19994                         ((e1->m1 == e2->m1) && (e1->m2 < e2->m2) ))
  2864. 19995                         ;       /* null statement */
  2865. 19996                                 /* i.e., don't add or subtract */
  2866. 19997                 else    {
  2867. 19998                         result.l_32++;  /* ADD  */
  2868. 19999                         if (e2->m2 > e1->m2)
  2869. 20000                                 e1->m1 -= 1;    /* carry in */
  2870. 20001                         e1->m1 -= e2->m1;       /* do SUBTRACTION */
  2871. 20002                         e1->m2 -= e2->m2;       /*    SUBTRACTION */
  2872. 20003                 }
  2873. 20004
  2874. 20005                 /*      shift dividend left one bit OR  */
  2875. 20006                 /*      IF it equals ZERO we can break out      */
  2876. 20007                 /*      of the loop, but still must shift       */
  2877. 20008                 /*      the quotient the remaining count bits   */
  2878. 20009                 /* NB   save the results of this test in error  */
  2879. 20010                 /*      if not zero, then the result is inexact. */
  2880. 20011                 /*      this would be reported in IEEE standard */
  2881. 20012
  2882. 20013                 /*      lp points to dividend                   */
  2883. 20014                 lp = &e1->m1;
  2884. 20015
  2885. 20016                 error = ((*lp | *(lp+1)) != 0L) ? 1 : 0;
  2886. 20017                 if (error)      {       /* more work */
  2887. 20018                         /*      assume max bit == 0 (see above) */
  2888. 20019                         b64_lsft(&e1->mantissa);
  2889. 20020                         continue;
  2890. 20021                 }
  2891. 20022                 else
  2892. 20023                         break;  /* leave loop   */
  2893. 20024         }       /* end of divide by subtraction loop    */
  2894. 20025
  2895. 20026         if (count > 0)  {
  2896. 20027                 lp = &result.h_32;
  2897. 20028                 if (count > 31) {       /* move to higher word */
  2898. 20029                         *lp = *(lp+1);
  2899. 20030                         count -= 32;
  2900. 20031                         *(lp+1) = 0L;   /* clear low word       */
  2901. 20032                 }
  2902. 20033                 if (*lp)
  2903. 20034                         *lp <<= count;  /* shift rest of way    */
  2904. 20035                 lp++;   /*  == &result.l_32     */
  2905. 20036                 if (*lp) {
  2906. 20037                         result.h_32 |= (*lp >> 32-count);
  2907. 20038                         *lp <<= count;
  2908. 20039                 }
  2909. 20040         }
  2910. 20041 #else /* USE_DIVIDE */
  2911. 20042
  2912. 20043         u[4] = (e1->m2 & 1) << 15;
  2913. 20044         b64_rsft(&(e1->mantissa));
  2914. 20045         u[0] = e1->m1 >> 16;
  2915. 20046         u[1] = e1->m1;
  2916. 20047         u[2] = e1->m2 >> 16;
  2917. 20048         u[3] = e1->m2;
  2918. 20049         u[5] = 0; u[6] = 0; u[7] = 0;
  2919. 20050         v[1] = e2->m1 >> 16;
  2920. 20051         v[2] = e2->m1;
  2921. 20052         v[3] = e2->m2 >> 16;
  2922. 20053         v[4] = e2->m2;
  2923. 20054         while (! v[maxv]) maxv--;
  2924. 20055         result.h_32 = 0;
  2925. 20056         result.l_32 = 0;
  2926. 20057         lp = &result.h_32;
  2927. 20058
  2928. 20059         /*
  2929. 20060          * Use an algorithm of Knuth (The art of programming, Seminumerical
  2930. 20061          * algorithms), to divide u by v. u and v are both seen as numbers
  2931. 20062          * with base 65536. 
  2932. 20063          */
  2933. 20064         for (j = 0; j <= 3; j++, u_p++) {
  2934. 20065                 unsigned long q_est, temp;
  2935. 20066
  2936. 20067                 if (j == 2) lp++;
  2937. 20068                 if (u_p[0] == 0 && u_p[1] < v[1]) continue;
  2938. 20069                 temp = ((unsigned long)u_p[0] << 16) + u_p[1];
  2939. 20070                 if (u_p[0] >= v[1]) {
  2940. 20071                         q_est = 0x0000FFFFL;
  2941. 20072                 }
  2942. 20073                 else {
  2943. 20074                         q_est = temp / v[1];
  2944. 20075                 }
  2945. 20076                 temp -= q_est * v[1];
  2946. 20077                 while (temp < 0x10000 && v[2]*q_est > ((temp<<16)+u_p[2])) {
  2947. 20078                         q_est--;
  2948. 20079                         temp += v[1];
  2949. 20080                 }
  2950. 20081                 /*      Now, according to Knuth, we have an estimate of the
  2951. 20082                         quotient, that is either correct or one too big, but
  2952. 20083                         almost always correct.
  2953. 20084                 */
  2954. 20085                 if (q_est != 0)  {
  2955. 20086                         int i;
  2956. 20087                         unsigned long k = 0;
  2957. 20088                         int borrow = 0;
  2958. 20089
  2959. 20090                         for (i = maxv; i > 0; i--) {
  2960. 20091                                 unsigned long tmp = q_est * v[i] + k + borrow;
  2961. 20092                                 unsigned short md = tmp;
  2962. 20093
  2963. 20094                                 borrow = (md > u_p[i]);
  2964. 20095                                 u_p[i] -= md;
  2965. 20096                                 k = tmp >> 16;
  2966. 20097                         }
  2967. 20098                         k += borrow;
  2968. 20099                         borrow = u_p[0] < k;
  2969. 20100                         u_p[0] -= k;
  2970. 20101
  2971. 20102                         if (borrow) {
  2972. 20103                                 /* So, this does not happen often; the estimate
  2973. 20104                                    was one too big; correct this
  2974. 20105                                 */
  2975. 20106                                 *lp |= (j & 1) ? (q_est - 1) : ((q_est-1)<<16);
  2976. 20107                                 borrow = 0;
  2977. 20108                                 for (i = maxv; i > 0; i--) {
  2978. 20109                                         unsigned long tmp 
  2979. 20110                                             = v[i]+(unsigned long)u_p[i]+borrow;
  2980. 20111                                         
  2981. 20112                                         u_p[i] = tmp;
  2982. 20113                                         borrow = tmp >> 16;
  2983. 20114                                 }
  2984. 20115                                 u_p[0] += borrow;
  2985. 20116                         }
  2986. 20117                         else *lp |= (j & 1) ? q_est : (q_est<<16);
  2987. 20118                 }
  2988. 20119         }
  2989. 20120 #ifdef  EXCEPTION_INEXACT
  2990. 20121         u_p = &u[0];
  2991. 20122         for (j = 7; j >= 0; j--) {
  2992. 20123                 if (*u_p++) {
  2993. 20124                         error = 1;
  2994. 20125                         break;
  2995. 20126                 }
  2996. 20127         }
  2997. 20128 #endif
  2998. 20129 #endif
  2999. 20130
  3000. 20131 #ifdef  EXCEPTION_INEXACT
  3001. 20132         if (error)      {
  3002. 20133                 /*
  3003. 20134                  * report here exception 8.5 - Inexact
  3004. 20135                  * from Draft 8.0 of IEEE P754:
  3005. 20136                  * In the absence of an invalid operation exception,
  3006. 20137                  * if the rounded result of an operation is not exact or if
  3007. 20138                  * it overflows without a trap, then the inexact exception
  3008. 20139                  * shall be assigned. The rounded or overflowed result
  3009. 20140                  * shall be delivered to the destination.
  3010. 20141                  */
  3011. 20142                 INEXACT();
  3012. 20143 #endif
  3013. 20144         e1->mantissa = result;
  3014. 20145
  3015. 20146         nrm_ext(e1);
  3016. 20147         if (e1->exp < EXT_MIN)  {
  3017. 20148                 /*
  3018. 20149                  * Exception 8.4 - Underflow
  3019. 20150                  */
  3020. 20151                 trap(EFUNFL);   /* underflow */
  3021. 20152                 e1->exp = EXT_MIN;
  3022. 20153                 e1->m1 = e1->m2 = 0L;
  3023. 20154                 return;
  3024. 20155         }
  3025. 20156         if (e1->exp >= EXT_MAX) {
  3026. 20157                 /*
  3027. 20158                  * Exception 8.3 - Overflow
  3028. 20159                  */
  3029. 20160                 trap(EFOVFL);   /* overflow */
  3030. 20161                 e1->exp = EXT_MAX;
  3031. 20162                 e1->m1 = e1->m2 = 0L;
  3032. 20163                 return;
  3033. 20164         }
  3034. 20165 }
  3035. ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  3036. src/lib/float/dvf4.c    
  3037. ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  3038. 20200 /*
  3039. 20201   (c) copyright 1988 by the Vrije Universiteit, Amsterdam, The Netherlands.
  3040. 20202   See the copyright notice in the ACK home directory, in the file "Copyright".
  3041. 20203 */
  3042. 20204
  3043. 20205 /* $Header: dvf4.c,v 1.5 93/01/05 12:04:53 ceriel Exp $ */
  3044. 20206
  3045. 20207 /*
  3046. 20208         DIVIDE TWO SINGLES - SINGLE Precision (dvf 4)
  3047. 20209 */
  3048. 20210
  3049. 20211 #include        "FP_types.h"
  3050. 20212
  3051. 20213 void
  3052. 20214 dvf4(s2,s1)
  3053. 20215 SINGLE  s1,s2;
  3054. 20216 {
  3055. 20217         EXTEND  e1,e2;
  3056. 20218
  3057. 20219         extend(&s1,&e1,sizeof(SINGLE));
  3058. 20220         extend(&s2,&e2,sizeof(SINGLE));
  3059. 20221
  3060. 20222                 /* do a divide */
  3061. 20223         div_ext(&e1,&e2);
  3062. 20224         compact(&e1,&s1,sizeof(SINGLE));
  3063. 20225 }
  3064. ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  3065. src/lib/float/dvf8.c    
  3066. ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  3067. 20300 /*
  3068. 20301   (c) copyright 1988 by the Vrije Universiteit, Amsterdam, The Netherlands.
  3069. 20302   See the copyright notice in the ACK home directory, in the file "Copyright".
  3070. 20303 */
  3071. 20304
  3072. 20305 /* $Header: dvf8.c,v 1.5 93/01/05 12:04:59 ceriel Exp $ */
  3073. 20306
  3074. 20307 /*
  3075. 20308         DIVIDE TWO FLOATS - DOUBLE Precision (DVF 8)
  3076. 20309 */
  3077. 20310
  3078. 20311 #include        "FP_types.h"
  3079. 20312
  3080. 20313 void
  3081. 20314 dvf8(s2,s1)
  3082. 20315 DOUBLE  s1,s2;
  3083. 20316 {
  3084. 20317         EXTEND  e1,e2;
  3085. 20318
  3086. 20319         extend(&s1.d[0],&e1,sizeof(DOUBLE));
  3087. 20320         extend(&s2.d[0],&e2,sizeof(DOUBLE));
  3088. 20321
  3089. 20322                 /* do a divide */
  3090. 20323         div_ext(&e1,&e2);
  3091. 20324         compact(&e1,&s1.d[0],sizeof(DOUBLE));
  3092. 20325 }
  3093. ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  3094. src/lib/float/extend.c    
  3095. ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  3096. 20400 /*
  3097. 20401   (c) copyright 1988 by the Vrije Universiteit, Amsterdam, The Netherlands.
  3098. 20402   See the copyright notice in the ACK home directory, in the file "Copyright".
  3099. 20403 */
  3100. 20404
  3101. 20405 /* $Header: extend.c,v 1.11 93/01/05 12:05:05 ceriel Exp $ */
  3102. 20406
  3103. 20407 /*
  3104. 20408         CONVERTS FLOATING POINT TO EXTENDED FORMAT
  3105. 20409
  3106. 20410         Two sizes of FLOATING Point are known:
  3107. 20411                 SINGLE and DOUBLE
  3108. 20412 */
  3109. 20413 /********************************************************/
  3110. 20414 /*
  3111. 20415         It is not required to normalize in extended
  3112. 20416         format, but it has been chosen to do so.
  3113. 20417         Extended Format is as follows (at exit):
  3114. 20418
  3115. 20419 ->sign  S000 0000 | 0000 0000           <SIGN>
  3116. 20420 ->exp   0EEE EEEE | EEEE EEEE           <EXPONENT>
  3117. 20421 ->m1    LFFF FFFF | FFFF FFFF           <L.Fraction>
  3118. 20422         FFFF FFFF | FFFF FFFF           <Fraction>
  3119. 20423 ->m2    FFFF FFFF | FFFF FFFF           <Fraction>
  3120. 20424         FFFF F000 | 0000 0000           <Fraction>
  3121. 20425 */
  3122. 20426 /********************************************************/
  3123. 20427
  3124. 20428 #include "FP_bias.h"
  3125. 20429 #include "FP_shift.h"
  3126. 20430 #include "FP_types.h"
  3127. 20431 #include "get_put.h"
  3128. 20432 /********************************************************/
  3129. 20433
  3130. 20434 void
  3131. 20435 extend(from,to,size)
  3132. 20436 unsigned long   *from;
  3133. 20437 EXTEND  *to;
  3134. 20438 int     size;
  3135. 20439 {
  3136. 20440         register char *cpt1;
  3137. 20441         unsigned long   tmp;
  3138. 20442         int     leadbit = 0;
  3139. 20443
  3140. 20444         cpt1 = (char *) from;
  3141. 20445
  3142. 20446 #if FL_MSL_AT_LOW_ADDRESS
  3143. 20447 #if FL_MSW_AT_LOW_ADDRESS
  3144. 20448         to->exp = uget2(cpt1);
  3145. 20449 #else
  3146. 20450         to->exp = uget2(cpt1+2);
  3147. 20451 #endif
  3148. 20452 #else
  3149. 20453 #if FL_MSW_AT_LOW_ADDRESS
  3150. 20454         to->exp = uget2(cpt1+(size == sizeof(DOUBLE) ? 4 : 0));
  3151. 20455 #else
  3152. 20456         to->exp = uget2(cpt1+(size == sizeof(DOUBLE) ? 6 : 2));
  3153. 20457 #endif
  3154. 20458 #endif
  3155. 20459         to->sign = (to->exp & 0x8000);  /* set sign bit */
  3156. 20460         to->exp ^= to->sign;
  3157. 20461         if (size == sizeof(DOUBLE))
  3158. 20462                 to->exp >>= DBL_EXPSHIFT;
  3159. 20463         else
  3160. 20464                 to->exp >>= SGL_EXPSHIFT;
  3161. 20465         if (to->exp > 0)
  3162. 20466                 leadbit++;      /* will set Lead bit later      */
  3163. 20467         else to->exp++;
  3164. 20468
  3165. 20469         if (size == sizeof(DOUBLE))     {
  3166. 20470 #if FL_MSL_AT_LOW_ADDRESS
  3167. 20471                 to->m1 = get4(cpt1);
  3168. 20472                 cpt1 += 4;
  3169. 20473                 tmp = get4(cpt1);
  3170. 20474 #else
  3171. 20475                 tmp = get4(cpt1);
  3172. 20476                 cpt1 += 4;
  3173. 20477                 to->m1 = get4(cpt1);
  3174. 20478 #endif
  3175. 20479                 if (to->exp == 1 && to->m1 == 0 && tmp == 0) {
  3176. 20480                         to->exp = 0;
  3177. 20481                         to->sign = 0;
  3178. 20482                         to->m1 = 0;
  3179. 20483                         to->m2 = 0;
  3180. 20484                         return;
  3181. 20485                 }
  3182. 20486                 to->m1 <<= DBL_M1LEFT;          /* shift        */
  3183. 20487                 to->exp -= DBL_BIAS;            /* remove bias  */
  3184. 20488                 to->m1 |= (tmp>>DBL_RPACK);     /* plus 10 == 32        */
  3185. 20489                 to->m2 = (tmp<<DBL_LPACK);      /* plus 22 == 32        */
  3186. 20490         }
  3187. 20491         else    {       /* size == sizeof(SINGLE)               */
  3188. 20492                 to->m1 = get4(cpt1);
  3189. 20493                 to->m1  <<= SGL_M1LEFT; /* shift        */
  3190. 20494                 if (to->exp == 1 && to->m1 == 0) {
  3191. 20495                         to->exp = 0;
  3192. 20496                         to->sign = 0;
  3193. 20497                         to->m1 = 0;
  3194. 20498                         to->m2 = 0;
  3195. 20499                         return;
  3196. 20500                 }
  3197. 20501                 to->exp -= SGL_BIAS;            /* remove bias  */
  3198. 20502                 to->m2 = 0L;
  3199. 20503         }
  3200. 20504
  3201. 20505         to->m1 |= NORMBIT;                              /* set bit L    */
  3202. 20506         if (leadbit == 0) {             /* set or clear Leading Bit     */
  3203. 20507                 to->m1 &= ~NORMBIT;                     /* clear bit L  */
  3204. 20508                 nrm_ext(to);                            /* and normalize */
  3205. 20509         }
  3206. 20510 }
  3207. ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  3208. src/lib/float/fef4.c    
  3209. ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  3210. 20600 /*
  3211. 20601   (c) copyright 1988 by the Vrije Universiteit, Amsterdam, The Netherlands.
  3212. 20602   See the copyright notice in the ACK home directory, in the file "Copyright".
  3213. 20603 */
  3214. 20604
  3215. 20605 /* $Header: fef4.c,v 1.7 93/01/05 12:05:12 ceriel Exp $ */
  3216. 20606
  3217. 20607 /*
  3218. 20608         SEPERATE INTO EXPONENT AND FRACTION (FEF 4)
  3219. 20609 */
  3220. 20610
  3221. 20611 #include        "FP_types.h"
  3222. 20612
  3223. 20613 void
  3224. 20614 fef4(r,s1)
  3225. 20615 SINGLE  s1;
  3226. 20616 struct fef4_returns     *r;
  3227. 20617 {
  3228. 20618         EXTEND  buf;
  3229. 20619         register struct fef4_returns    *p = r; /* make copy; r might refer
  3230. 20620                                                    to itself (see table)
  3231. 20621                                                 */
  3232. 20622
  3233. 20623         extend(&s1,&buf,sizeof(SINGLE));
  3234. 20624         if (buf.exp == 0 && buf.m1 == 0 && buf.m2 == 0) {
  3235. 20625                 p->e = 0;
  3236. 20626         }
  3237. 20627         else {
  3238. 20628                 p->e = buf.exp+1;
  3239. 20629                 buf.exp = -1;
  3240. 20630         }
  3241. 20631         compact(&buf,&p->f,sizeof(SINGLE));
  3242. 20632 }
  3243. ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  3244. src/lib/float/fef8.c    
  3245. ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  3246. 20700 /*
  3247. 20701   (c) copyright 1988 by the Vrije Universiteit, Amsterdam, The Netherlands.
  3248. 20702   See the copyright notice in the ACK home directory, in the file "Copyright".
  3249. 20703 */
  3250. 20704
  3251. 20705 /* $Header: fef8.c,v 1.7 93/01/05 12:05:18 ceriel Exp $ */
  3252. 20706
  3253. 20707 /*
  3254. 20708         SEPERATE DOUBLE INTO EXPONENT AND FRACTION (FEF 8)
  3255. 20709 */
  3256. 20710
  3257. 20711 #include        "FP_types.h"
  3258. 20712
  3259. 20713 void
  3260. 20714 fef8(r, s1)
  3261. 20715 DOUBLE  s1;
  3262. 20716 struct fef8_returns *r;
  3263. 20717 {
  3264. 20718         EXTEND  buf;
  3265. 20719         register struct fef8_returns *p = r;    /* make copy, r might refer
  3266. 20720                                                    to itself (see table)
  3267. 20721                                                 */
  3268. 20722
  3269. 20723         extend(&s1.d[0],&buf,sizeof(DOUBLE));
  3270. 20724         if (buf.exp == 0 && buf.m1 == 0 && buf.m2 == 0) {
  3271. 20725                 p->e = 0;
  3272. 20726         }
  3273. 20727         else {
  3274. 20728                 p->e = buf.exp + 1;
  3275. 20729                 buf.exp = -1;
  3276. 20730         }
  3277. 20731         compact(&buf,&p->f.d[0],sizeof(DOUBLE));
  3278. 20732 }
  3279. ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  3280. src/lib/float/fif4.c    
  3281. ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  3282. 20800 /*
  3283. 20801   (c) copyright 1988 by the Vrije Universiteit, Amsterdam, The Netherlands.
  3284. 20802   See the copyright notice in the ACK home directory, in the file "Copyright".
  3285. 20803 */
  3286. 20804
  3287. 20805 /* $Header: fif4.c,v 1.7 93/01/05 12:05:24 ceriel Exp $ */
  3288. 20806
  3289. 20807 /*
  3290. 20808         MULTIPLY AND DISMEMBER PARTS (FIF 4)
  3291. 20809 */
  3292. 20810
  3293. 20811 #include "FP_types.h"
  3294. 20812 #include "FP_shift.h"
  3295. 20813
  3296. 20814 void
  3297. 20815 fif4(p,x,y)
  3298. 20816 SINGLE  x,y;
  3299. 20817 struct fif4_returns *p;
  3300. 20818 {
  3301. 20819
  3302. 20820         EXTEND  e1,e2;
  3303. 20821
  3304. 20822         extend(&y,&e1,sizeof(SINGLE));
  3305. 20823         extend(&x,&e2,sizeof(SINGLE));
  3306. 20824                 /* do a multiply */
  3307. 20825         mul_ext(&e1,&e2);
  3308. 20826         e2 = e1;
  3309. 20827         compact(&e2,&y,sizeof(SINGLE));
  3310. 20828         if (e1.exp < 0) {
  3311. 20829                 p->ipart = 0;
  3312. 20830                 p->fpart = y;
  3313. 20831                 return;
  3314. 20832         }
  3315. 20833         if (e1.exp > 30 - SGL_M1LEFT) {
  3316. 20834                 p->ipart = y;
  3317. 20835                 p->fpart = 0;
  3318. 20836                 return;
  3319. 20837         }
  3320. 20838         b64_sft(&e1.mantissa, 63 - e1.exp);
  3321. 20839         b64_sft(&e1.mantissa, e1.exp - 63);     /* "loose" low order bits */
  3322. 20840         compact(&e1,&(p->ipart),sizeof(SINGLE));
  3323. 20841         extend(&(p->ipart), &e2, sizeof(SINGLE));
  3324. 20842         extend(&y, &e1, sizeof(SINGLE));
  3325. 20843         sub_ext(&e1, &e2);
  3326. 20844         compact(&e1, &(p->fpart), sizeof(SINGLE));
  3327. 20845 }
  3328. ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  3329. src/lib/float/fif8.c    
  3330. ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  3331. 20900 /*
  3332. 20901   (c) copyright 1988 by the Vrije Universiteit, Amsterdam, The Netherlands.
  3333. 20902   See the copyright notice in the ACK home directory, in the file "Copyright".
  3334. 20903 */
  3335. 20904
  3336. 20905 /* $Header: fif8.c,v 1.7 93/01/05 12:05:30 ceriel Exp $ */
  3337. 20906
  3338. 20907 /*
  3339. 20908         MULTIPLY AND DISMEMBER PARTS (FIF 8)
  3340. 20909 */
  3341. 20910
  3342. 20911 #include "FP_types.h"
  3343. 20912 #include "FP_shift.h"
  3344. 20913
  3345. 20914 void
  3346. 20915 fif8(p,x,y)
  3347. 20916 DOUBLE  x,y;
  3348. 20917 struct fif8_returns *p;
  3349. 20918 {
  3350. 20919
  3351. 20920         EXTEND  e1,e2;
  3352. 20921
  3353. 20922         extend(&y.d[0],&e1,sizeof(DOUBLE));
  3354. 20923         extend(&x.d[0],&e2,sizeof(DOUBLE));