Source:NetHack 3.1.0/end.c
Jump to navigation
Jump to search
Below is the full text to end.c from the source code of NetHack 3.1.0.
Warning! This is the source code from an old release. For newer releases, see Source code
The NetHack General Public License applies to screenshots, source code and other content from NetHack.
This content was modified from the original NetHack source code distribution (by splitting up NetHack content between wiki pages, and possibly further editing). See the page history for a list of who changed it, and on what dates.
1. /* SCCS Id: @(#)end.c 3.1 93/01/15 */ 2. /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ 3. /* NetHack may be freely redistributed. See license for details. */ 4. 5. #define NEED_VARARGS /* comment line for pre-compiled headers */ 6. 7. #include "hack.h" 8. #include "eshk.h" 9. #ifndef NO_SIGNAL 10. #include <signal.h> 11. #endif 12. 13. STATIC_PTR int NDECL(done_intr); 14. static void FDECL(disclose,(int,BOOLEAN_P)); 15. static struct obj *FDECL(get_valuables, (struct obj *)); 16. static void FDECL(savelife, (int)); 17. 18. /* 19. * The order of these needs to match the macros in hack.h. 20. */ 21. static const char NEARDATA *deaths[] = { /* the array of death */ 22. "died", "choked", "poisoned", "starvation", "drowning", 23. "burning", "crushed", "turned to stone", "genocided", 24. "panic", "trickery", 25. "quit", "escaped", "ascended" 26. }; 27. 28. static const char NEARDATA *ends[] = { /* "when you..." */ 29. "died", "choked", "were poisoned", "starved", "drowned", 30. "burned", "were crushed", "turned to stone", "were genocided", 31. "panicked", "were tricked", 32. "quit", "escaped", "ascended" 33. }; 34. 35. int 36. done1() 37. { 38. #ifndef NO_SIGNAL 39. (void) signal(SIGINT,SIG_IGN); 40. #endif 41. if(flags.ignintr) { 42. #ifndef NO_SIGNAL 43. (void) signal(SIGINT, (SIG_RET_TYPE) done1); 44. #endif 45. clear_nhwindow(WIN_MESSAGE); 46. curs_on_u(); 47. wait_synch(); 48. if(multi > 0) nomul(0); 49. return 0; 50. } 51. return done2(); 52. } 53. 54. int 55. done2() 56. { 57. if(yn("Really quit?") == 'n') { 58. #ifndef NO_SIGNAL 59. (void) signal(SIGINT, (SIG_RET_TYPE) done1); 60. #endif 61. clear_nhwindow(WIN_MESSAGE); 62. curs_on_u(); 63. wait_synch(); 64. if(multi > 0) nomul(0); 65. if(multi == 0) { 66. u.uinvulnerable = FALSE; /* avoid ctrl-C bug -dlc */ 67. u.usleep = 0; 68. } 69. return 0; 70. } 71. #if defined(WIZARD) && (defined(UNIX) || defined(VMS) || defined(LATTICE)) 72. if(wizard) { 73. # ifdef VMS 74. const char *tmp = "Enter debugger?"; 75. # else 76. # ifdef LATTICE 77. const char *tmp = "Create SnapShot?"; 78. # else 79. const char *tmp = "Dump core?"; 80. # endif 81. # endif 82. if(yn(tmp) == 'y') { 83. (void) signal(SIGINT, (SIG_RET_TYPE) done1); 84. exit_nhwindows(NULL); 85. #ifdef AMIGA 86. Abort(0); 87. #else 88. # ifdef SYSV 89. (void) 90. # endif 91. abort(); 92. #endif 93. } 94. } 95. #endif 96. #ifndef LINT 97. done(QUIT); 98. #endif 99. return 0; 100. } 101. 102. STATIC_PTR 103. int 104. done_intr(){ 105. done_stopprint++; 106. #ifndef NO_SIGNAL 107. (void) signal(SIGINT, SIG_IGN); 108. # if defined(UNIX) || defined(VMS) 109. (void) signal(SIGQUIT, SIG_IGN); 110. # endif 111. #endif /* NO_SIGNAL /* */ 112. return 0; 113. } 114. 115. #if defined(UNIX) || defined(VMS) 116. static 117. int 118. done_hangup(){ 119. done_hup++; 120. (void)signal(SIGHUP, SIG_IGN); 121. (void)done_intr(); 122. return 0; 123. } 124. #endif 125. 126. void 127. done_in_by(mtmp) 128. register struct monst *mtmp; 129. { 130. char buf[BUFSZ]; 131. 132. You("die..."); 133. buf[0] = '\0'; 134. if (type_is_pname(mtmp->data) || (mtmp->data->geno & G_UNIQ)) { 135. if (!(type_is_pname(mtmp->data) && (mtmp->data->geno & G_UNIQ))) 136. Strcat(buf, "the "); 137. killer_format = KILLED_BY; 138. } 139. if (mtmp->minvis) 140. Strcat(buf, "invisible "); 141. if (Hallucination) 142. Strcat(buf, "hallucinogen-distorted "); 143. 144. if(mtmp->data == &mons[PM_GHOST]) { 145. register char *gn = (char *) mtmp->mextra; 146. if (!Hallucination && !mtmp->minvis && *gn) { 147. Strcat(buf, "the "); 148. killer_format = KILLED_BY; 149. } 150. Sprintf(eos(buf), (*gn ? "ghost of %s" : "ghost%s"), gn); 151. } else if(mtmp->isshk) { 152. Sprintf(eos(buf), "%s %s, the shopkeeper", 153. (mtmp->female ? "Ms." : "Mr."), shkname(mtmp)); 154. killer_format = KILLED_BY; 155. } else if (mtmp->ispriest || mtmp->isminion) { 156. killer = priestname(mtmp); 157. if (!strncmp(killer, "the ", 4)) Strcat(buf, killer+4); 158. else Strcat(buf, killer); 159. } else Strcat(buf, mtmp->data->mname); 160. if (mtmp->mnamelth) Sprintf(eos(buf), " called %s", NAME(mtmp)); 161. killer = buf; 162. if (mtmp->data->mlet == S_WRAITH) 163. u.ugrave_arise = PM_WRAITH; 164. else if (mtmp->data->mlet == S_MUMMY) 165. u.ugrave_arise = (pl_character[0]=='E') ? 166. PM_ELF_MUMMY : PM_HUMAN_MUMMY; 167. else if (mtmp->data->mlet == S_VAMPIRE) 168. u.ugrave_arise = PM_VAMPIRE; 169. if (u.ugrave_arise > -1 && (mons[u.ugrave_arise].geno & G_GENOD)) 170. u.ugrave_arise = -1; 171. if (mtmp->data->mlet == S_COCKATRICE) 172. done(STONING); 173. else 174. done(DIED); 175. return; 176. } 177. 178. /*VARARGS1*/ 179. boolean panicking; 180. extern boolean hu; /* from save.c */ 181. 182. void 183. panic VA_DECL(const char *, str) 184. VA_START(str); 185. VA_INIT(str, char *); 186. 187. if(panicking++) 188. #ifdef AMIGA 189. Abort(0); 190. #else 191. # ifdef SYSV 192. (void) 193. # endif 194. abort(); /* avoid loops - this should never happen*/ 195. #endif 196. 197. if (flags.window_inited) exit_nhwindows(NULL); 198. flags.window_inited = 0; /* they're gone; force raw_print()ing */ 199. 200. raw_print(" Suddenly, the dungeon collapses."); 201. #if defined(WIZARD) && !defined(MICRO) 202. if(!wizard) { 203. raw_printf("Report error to %s and it may be possible to rebuild.", 204. # ifdef WIZARD_NAME /*(KR1ED)*/ 205. WIZARD_NAME); 206. # else 207. WIZARD); 208. # endif 209. } 210. set_error_savefile(); 211. hu = FALSE; 212. (void) dosave0(); 213. #endif 214. { 215. char buf[BUFSZ]; 216. Vsprintf(buf,str,VA_ARGS); 217. raw_print(buf); 218. } 219. #if defined(WIZARD) && (defined(UNIX) || defined(VMS) || defined(LATTICE)) 220. if (wizard) 221. # ifdef AMIGA 222. Abort(0); 223. # else 224. # ifdef SYSV 225. (void) 226. # endif 227. abort(); /* generate core dump */ 228. # endif 229. #endif 230. VA_END(); 231. done(PANICKED); 232. } 233. 234. static void 235. disclose(how,taken) 236. int how; 237. boolean taken; 238. { 239. char c; 240. char qbuf[QBUFSZ]; 241. 242. if(invent) { 243. if(taken) 244. Sprintf(qbuf,"Do you want to see what you had when you %s?", 245. (how == QUIT) ? "quit" : "died"); 246. else 247. Strcpy(qbuf,"Do you want your possessions identified?"); 248. if ((c = yn_function(qbuf, ynqchars, 'y')) == 'y') { 249. /* New dump format by maartenj@cs.vu.nl */ 250. struct obj *obj; 251. 252. for(obj = invent; obj && !done_stopprint; obj = obj->nobj) { 253. makeknown(obj->otyp); 254. obj->known = obj->bknown = obj->dknown = obj->rknown = 1; 255. } 256. (void) display_inventory(NULL, FALSE); 257. container_contents(invent, TRUE, TRUE); 258. } 259. if (c == 'q') done_stopprint++; 260. if (taken) { 261. /* paybill has already given the inventory locations 262. * in the shop and put it on the main object list 263. */ 264. struct obj *obj; 265. 266. for(obj = invent; obj; obj = obj->nobj) { 267. obj->owornmask = 0; 268. if(rn2(5)) curse(obj); 269. } 270. invent = (struct obj *) 0; 271. } 272. } 273. 274. if (!done_stopprint) { 275. c = yn_function("Do you want to see your intrinsics?",ynqchars,'y'); 276. if (c == 'y') enlightenment(TRUE); /* final */ 277. if (c == 'q') done_stopprint++; 278. } 279. 280. } 281. 282. /* try to get the player back in a viable state after being killed */ 283. static void 284. savelife(how) 285. int how; 286. { 287. u.uswldtim = 0; 288. u.uhp = u.uhpmax; 289. if (u.uhunger < 500) { 290. u.uhunger = 500; 291. newuhs(FALSE); 292. } 293. if (how == CHOKING) init_uhunger(); 294. nomovemsg = "You survived that attempt on your life."; 295. flags.move = 0; 296. if(multi > 0) multi = 0; else multi = -1; 297. if(u.utrap && u.utraptype == TT_LAVA) u.utrap = 0; 298. flags.botl = 1; 299. u.ugrave_arise = -1; 300. curs_on_u(); 301. } 302. 303. /* 304. * Get valuables from the given list. NOTE: The list is destroyed as it is 305. * processed, so don't expect to use it again! 306. */ 307. static struct obj * 308. get_valuables(list) 309. struct obj *list; 310. { 311. struct obj *obj, *next_obj, *c_vals, *temp; 312. struct obj *valuables = (struct obj *)0; 313. 314. for (obj = list; obj; obj = next_obj) { 315. if (Is_container(obj) && obj->cobj) { 316. c_vals = get_valuables(obj->cobj); 317. 318. if (c_vals) { 319. /* find the end of the list */ 320. for (temp = c_vals; temp->nobj; temp = temp->nobj) ; 321. 322. temp->nobj = valuables; 323. valuables = c_vals; 324. } 325. } 326. 327. next_obj = obj->nobj; 328. 329. if ((obj->oclass == GEM_CLASS && obj->otyp < LUCKSTONE) 330. || obj->oclass == AMULET_CLASS) { 331. obj->nobj = valuables; 332. valuables = obj; 333. } 334. } 335. return valuables; 336. } 337. 338. /* Be careful not to call panic from here! */ 339. void 340. done(how) 341. int how; 342. { 343. struct permonst *upmon; 344. boolean taken; 345. char kilbuf[BUFSZ], pbuf[BUFSZ]; 346. winid endwin = WIN_ERR; 347. boolean have_windows = flags.window_inited; 348. 349. /* kilbuf: used to copy killer in case it comes from something like 350. * xname(), which would otherwise get overwritten when we call 351. * xname() when listing possessions 352. * pbuf: holds Sprintf'd output for raw_print and putstr 353. */ 354. if (how == ASCENDED) 355. killer_format = NO_KILLER_PREFIX; 356. /* Avoid killed by "a" burning or "a" starvation */ 357. if (!killer && (how == STARVING || how == BURNING)) 358. killer_format = KILLED_BY; 359. Strcpy(kilbuf, (!killer || how >= PANICKED ? deaths[how] : killer)); 360. killer = kilbuf; 361. #ifdef WIZARD 362. if (wizard && how == TRICKED) { 363. You("are a very tricky wizard, it seems."); 364. return; 365. } 366. #endif 367. if (Lifesaved && how <= GENOCIDED) { 368. pline("But wait..."); 369. makeknown(AMULET_OF_LIFE_SAVING); 370. Your("medallion %s!", 371. !Blind ? "begins to glow" : "feels warm"); 372. if (how == CHOKING) You("vomit ..."); 373. You("feel much better!"); 374. pline("The medallion crumbles to dust!"); 375. useup(uamul); 376. 377. (void) adjattrib(A_CON, -1, TRUE); 378. if(u.uhpmax <= 0) u.uhpmax = 10; /* arbitrary */ 379. savelife(how); 380. if (how == GENOCIDED) 381. pline("Unfortunately you are still genocided..."); 382. else { 383. killer = 0; 384. return; 385. } 386. } 387. #if defined(WIZARD) || defined(EXPLORE_MODE) 388. if ((wizard || discover) && how <= GENOCIDED) { 389. if(yn("Die?") == 'y') goto die; 390. pline("OK, so you don't %s.", 391. (how == CHOKING) ? "choke" : "die"); 392. if(u.uhpmax <= 0) u.uhpmax = u.ulevel * 8; /* arbitrary */ 393. savelife(how); 394. killer = 0; 395. return; 396. } 397. #endif /* WIZARD || EXPLORE_MODE */ 398. /* Sometimes you die on the first move. Life's not fair. 399. * On those rare occasions you get hosed immediately, go out 400. * smiling... :-) -3. 401. */ 402. if (moves <= 1 && how < QUIT) 403. /* You die... --More-- */ 404. pline("Do not pass go. Do not collect 200 zorkmids."); 405. 406. die: 407. if (have_windows) wait_synch(); /* flush screen output */ 408. #ifndef NO_SIGNAL 409. (void) signal(SIGINT, (SIG_RET_TYPE) done_intr); 410. # if defined(UNIX) || defined(VMS) 411. (void) signal(SIGQUIT, (SIG_RET_TYPE) done_intr); 412. (void) signal(SIGHUP, (SIG_RET_TYPE) done_hangup); 413. # endif 414. #endif /* NO_SIGNAL /* */ 415. #ifdef POLYSELF 416. if (u.mtimedone) 417. upmon = uasmon; 418. else 419. #endif 420. upmon = player_mon(); 421. 422. if (u.ugrave_arise < 0) { /* >= 0 means create no corpse */ 423. if (how == STONING) 424. u.ugrave_arise = -2; 425. 426. /* 427. * If you're burned to a crisp, why leave a corpse? 428. */ 429. else if (how != BURNING && how != PANICKED) 430. (void) mk_named_object(CORPSE, upmon, u.ux, u.uy, plname, 431. (int)strlen(plname)); 432. } 433. 434. if (how == QUIT) { 435. killer_format = NO_KILLER_PREFIX; 436. if (u.uhp < 1) { 437. how = DIED; 438. /* note that killer is pointing at kilbuf */ 439. Strcpy(kilbuf, "quit while already on Charon's boat"); 440. } 441. } 442. if (how == ESCAPED || how == PANICKED) 443. killer_format = NO_KILLER_PREFIX; 444. 445. /* paybill() must be called unconditionally, or strange things will 446. * happen to bones levels */ 447. taken = paybill(how != QUIT); 448. paygd(); 449. clearlocks(); 450. #ifdef AMIGA 451. clear_icon(); 452. #endif 453. if (have_windows) display_nhwindow(WIN_MESSAGE, FALSE); 454. 455. if (flags.end_disclose && how != PANICKED) disclose(how,taken); 456. 457. if (how < GENOCIDED) { 458. #ifdef WIZARD 459. if (!wizard || yn("Save bones?") == 'y') 460. #endif 461. savebones(); 462. } 463. 464. /* clean up unneeded windows */ 465. if (have_windows) { 466. destroy_nhwindow(WIN_MAP); 467. destroy_nhwindow(WIN_STATUS); 468. destroy_nhwindow(WIN_MESSAGE); 469. 470. if(!done_stopprint || flags.tombstone) 471. endwin = create_nhwindow(NHW_TEXT); 472. 473. if(how < GENOCIDED && flags.tombstone) outrip(how, endwin); 474. } else 475. done_stopprint = 1; /* just avoid any more output */ 476. 477. /* changing kilbuf really changes killer. we do it this way because 478. killer is declared a (const char *) 479. */ 480. if (u.uhave.amulet) Strcat(kilbuf, " (with the Amulet)"); 481. if (!done_stopprint) { 482. Sprintf(pbuf, "%s %s the %s...", 483. (pl_character[0]=='S') ? "Sayonara" : "Goodbye", plname, 484. how != ASCENDED ? (const char *) pl_character : 485. (const char *) (flags.female ? "Demigoddess" : "Demigod")); 486. putstr(endwin, 0, pbuf); 487. putstr(endwin, 0, ""); 488. } 489. { long tmp; 490. int deepest = deepest_lev_reached(FALSE); 491. 492. u.ugold += hidden_gold(); /* accumulate gold from containers */ 493. tmp = u.ugold - u.ugold0; 494. if (tmp < 0L) 495. tmp = 0L; 496. if (how < PANICKED) 497. tmp -= tmp / 10L; 498. u.urexp += tmp; 499. u.urexp += 50L * (long)(deepest - 1); 500. if (deepest > 20) 501. u.urexp += 1000L * (long)((deepest > 30) ? 10 : deepest - 20); 502. if (how == ASCENDED) u.urexp *= 2L; 503. } 504. if (how == ESCAPED || how == ASCENDED) { 505. register struct monst *mtmp; 506. register struct obj *otmp; 507. struct obj *jewels; 508. long i; 509. register long worthlessct = 0; 510. 511. /* 512. * Put items that count into the jewels chain. Rewriting 513. * the invent chain and all the container chains (within 514. * invent) here is safe. They will never be used again. 515. */ 516. jewels = get_valuables(invent); 517. 518. /* add points for jewels */ 519. for(otmp = jewels; otmp; otmp = otmp->nobj) { 520. if(otmp->oclass == GEM_CLASS) 521. u.urexp += otmp->quan * 522. objects[otmp->otyp].oc_cost; 523. else /* amulet */ 524. u.urexp += objects[otmp->otyp].oc_cost; 525. } 526. 527. keepdogs(); 528. viz_array[0][0] |= IN_SIGHT; /* need visibility for naming */ 529. mtmp = mydogs; 530. if(!done_stopprint) Strcpy(pbuf, "You"); 531. if(mtmp) { 532. while(mtmp) { 533. if(!done_stopprint) { 534. Strcat(pbuf, " and "); 535. Strcat(pbuf, mon_nam(mtmp)); 536. } 537. if(mtmp->mtame) 538. u.urexp += mtmp->mhp; 539. mtmp = mtmp->nmon; 540. } 541. if(!done_stopprint) 542. putstr(endwin, 0, pbuf); 543. pbuf[0] = 0; 544. } else { 545. if(!done_stopprint) 546. Strcat(pbuf, " "); 547. } 548. if(!done_stopprint) { 549. Sprintf(eos(pbuf), 550. "%s with %ld point%s,", 551. how==ASCENDED ? "went to your reward" 552. : "escaped from the dungeon", 553. u.urexp, plur(u.urexp)); 554. putstr(endwin, 0, pbuf); 555. } 556. 557. /* print jewels chain here */ 558. for(otmp = jewels; otmp; otmp = otmp->nobj) { 559. makeknown(otmp->otyp); 560. if(otmp->oclass == GEM_CLASS && 561. otmp->otyp < LUCKSTONE) { 562. i = otmp->quan * 563. objects[otmp->otyp].oc_cost; 564. if(i == 0) { 565. worthlessct += otmp->quan; 566. continue; 567. } 568. } else { /* amulet */ 569. otmp->known = 1; 570. i = objects[otmp->otyp].oc_cost; 571. } 572. if(!done_stopprint) { 573. Sprintf(pbuf, " %s (worth %ld zorkmids),", 574. doname(otmp), i); 575. putstr(endwin, 0, pbuf); 576. } 577. } 578. if(worthlessct && !done_stopprint) { 579. Sprintf(pbuf, 580. " %ld worthless piece%s of colored glass,", 581. worthlessct, plur(worthlessct)); 582. putstr(endwin, 0, pbuf); 583. } 584. } else if (!done_stopprint) { 585. Strcpy(pbuf, "You "); 586. Strcat(pbuf, ends[how]); 587. if (how != ASCENDED) { 588. Strcat(pbuf, " in "); 589. if (Is_astralevel(&u.uz)) 590. Strcat(pbuf, "The Astral Plane"); 591. else Strcat(pbuf, dungeons[u.uz.dnum].dname); 592. Strcat(pbuf, " "); 593. if (!In_endgame(&u.uz) 594. #ifdef MULDGN 595. && !Is_knox(&u.uz) 596. #endif 597. ) 598. Sprintf(eos(pbuf), "on dungeon level %d ", ( 599. #ifdef MULDGN 600. In_quest(&u.uz) ? 601. dunlev(&u.uz) : 602. #endif 603. depth(&u.uz))); 604. } 605. Sprintf(eos(pbuf), 606. "with %ld point%s,", u.urexp, plur(u.urexp)); 607. putstr(endwin, 0, pbuf); 608. } 609. if (!done_stopprint) { 610. Sprintf(pbuf, "and %ld piece%s of gold, after %ld move%s.", 611. u.ugold, plur(u.ugold), moves, plur(moves)); 612. putstr(endwin, 0, pbuf); 613. } 614. if (!done_stopprint) { 615. Sprintf(pbuf, 616. "You were level %u with a maximum of %d hit point%s when you %s.", 617. u.ulevel, u.uhpmax, plur(u.uhpmax), ends[how]); 618. putstr(endwin, 0, pbuf); 619. putstr(endwin, 0, ""); 620. } 621. #if (defined(WIZARD) || defined(EXPLORE_MODE)) 622. # ifndef LOGFILE 623. if (wizard || discover) { 624. if (!done_stopprint) { 625. putstr(endwin, 0, ""); 626. Sprintf(pbuf, "Since you were in %s mode, the score list \ 627. will not be checked.", wizard ? "wizard" : "discover"); 628. putstr(endwin, 0, pbuf); 629. putstr(endwin, 0, ""); 630. display_nhwindow(endwin, TRUE); 631. } 632. if (have_windows) 633. exit_nhwindows(NULL); 634. } else 635. # endif 636. #endif 637. { 638. if (!done_stopprint) 639. display_nhwindow(endwin, TRUE); 640. if (have_windows) 641. exit_nhwindows(NULL); 642. /* "So when I die, the first thing I will see in Heaven is a score list?" */ 643. topten(how); 644. } 645. if(done_stopprint) { raw_print(""); raw_print(""); } 646. terminate(0); 647. } 648. 649. 650. #ifdef NOSAVEONHANGUP 651. int 652. hangup() 653. { 654. (void) signal(SIGINT, SIG_IGN); 655. clearlocks(); 656. # ifndef VMS 657. terminate(1); 658. # endif 659. } 660. #endif 661. 662. 663. void 664. container_contents(list, identified, all_containers) 665. struct obj *list; 666. boolean identified, all_containers; 667. { 668. register struct obj *box, *obj; 669. char buf[BUFSZ]; 670. 671. for (box = list; box; box = box->nobj) { 672. if (Is_container(box) && box->otyp != BAG_OF_TRICKS) { 673. if (box->cobj) { 674. winid tmpwin = create_nhwindow(NHW_MENU); 675. Sprintf(buf, "Contents of the %s:", xname(box)); 676. putstr(tmpwin, 0, buf); putstr(tmpwin, 0, ""); 677. for (obj = box->cobj; obj; obj = obj->nobj) { 678. if (identified) { 679. makeknown(obj->otyp); 680. obj->known = obj->bknown = obj->dknown = 1; 681. } 682. putstr(tmpwin, 0, doname(obj)); 683. } 684. display_nhwindow(tmpwin, TRUE); 685. destroy_nhwindow(tmpwin); 686. if (all_containers) 687. container_contents(box->cobj, identified, TRUE); 688. } else { 689. pline("%s is empty.", The(xname(box))); 690. display_nhwindow(WIN_MESSAGE, FALSE); 691. } 692. } 693. if (!all_containers) 694. break; 695. } 696. } 697. 698. void 699. terminate(status) 700. int status; 701. { 702. #ifdef MAC 703. if (!hu) { 704. int idx; 705. for (idx = theWindows[BASE_WINDOW].windowTextLen; --idx >= 0; ) 706. /* If there is something to show... */ 707. if (((unsigned char *)*theWindows[BASE_WINDOW].windowText)[idx] > ' ') { 708. display_nhwindow(BASE_WINDOW, TRUE); 709. break; 710. } 711. } 712. #endif 713. exit(status); 714. } 715. 716. /*end.c*/