Source:NetHack 1.4f/makedefs.c
Jump to navigation
Jump to search
Below is the full text to makedefs.c from the source code of NetHack 1.4f. To link to a particular line, write [[NetHack 1.4f/makedefs.c#line123]], for example.
Warning! This is the source code from an old release. For the latest release, see Source code
Screenshots and source code from Hack are used under the CWI license.
1. /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ 2. /* makedefs.c - NetHack version 1.0 */ 3. 4. static char SCCS_Id[] = "@(#)makedefs.c 1.4\t87/08/08"; 5. 6. #include "config.h" 7. #include <stdio.h> 8. 9. #ifdef MSDOS 10. #undef exit 11. #define alloc malloc 12. #define RDMODE "r" 13. #define WRMODE "w" 14. #else 15. #define RDMODE "r+" 16. #define WRMODE "w+" 17. #endif 18. 19. /* construct definitions of object constants */ 20. #define OBJ_FILE "objects.h" 21. #define ONAME_FILE "onames.h" 22. #define TRAP_FILE "trap.h" 23. #define DATE_FILE "date.h" 24. #define RUMOR_FILE "rumors" 25. #define DATA_FILE "data" 26. 27. char inline[256], outline[256]; 28. 29. main(argc, argv) 30. int argc; 31. char *argv[]; 32. { 33. char *option; 34. 35. if(argc == 2) { 36. option = argv[1]; 37. switch (option[1]) { 38. 39. case 'o': 40. case 'O': do_objs(); 41. break; 42. case 't': 43. case 'T': do_traps(); 44. break; 45. case 'r': 46. case 'R': do_rumors(); 47. break; 48. 49. case 'd': do_data(); 50. break; 51. 52. case 'D': do_date(); 53. break; 54. default: 55. fprintf(stderr, "Unknown option '%c'.\n", option[1]); 56. exit(1); 57. } 58. exit(0); 59. } else fprintf(stderr, "Bad arg count (%d).\n", argc-1); 60. exit(1); 61. } 62. 63. do_traps() { 64. int ntrap, getpid(); 65. char tmpfile[30]; 66. FILE *freopen(); 67. 68. sprintf(tmpfile, "makedefs.%d", getpid()); 69. if(freopen(tmpfile, WRMODE, stdout) == NULL) { 70. 71. perror(tmpfile); 72. exit(1); 73. } 74. if(freopen(TRAP_FILE, RDMODE, stdin) == NULL) { 75. 76. perror(TRAP_FILE); 77. exit(1); 78. } 79. 80. while(gets(inline) != NULL) { 81. 82. puts(inline); 83. if(!strncmp(inline, "/* DO NOT REMOVE THIS LINE */", 29)) break; 84. } 85. ntrap = 10; 86. printf("\n"); 87. 88. #ifdef NEWTRAPS 89. printf("#define\tMGTRP\t\t%d\n", ntrap++); 90. printf("#define\tSQBRD\t\t%d\n", ntrap++); 91. #endif 92. #ifdef SPIDERS 93. printf("#define\tWEB\t\t%d\n", ntrap++); 94. #endif 95. #ifdef NEWCLASS 96. printf("#define\tSPIKED_PIT\t%d\n", ntrap++); 97. printf("#define\tLEVEL_TELEP\t%d\n", ntrap++); 98. #endif 99. #ifdef SPELLS 100. printf("#define\tANTI_MAGIC\t%d\n", ntrap++); 101. #endif 102. #ifdef KAA 103. printf("#define\tRUST_TRAP\t%d\n", ntrap++); 104. #endif 105. printf("\n#define\tTRAPNUM\t%d\n", ntrap); 106. fclose(stdin); 107. fclose(stdout); 108. #ifdef MSDOS 109. remove(TRAP_FILE); 110. #endif 111. rename(tmpfile, TRAP_FILE); 112. } 113. 114. 115. struct hline { 116. struct hline *next; 117. char *line; 118. } *f_line; 119. 120. do_rumors(){ 121. struct hline *c_line; 122. char infile[30]; 123. FILE *freopen(); 124. 125. if(freopen(RUMOR_FILE, WRMODE, stdout) == NULL) { 126. 127. perror(RUMOR_FILE); 128. exit(1); 129. } 130. #ifdef MSDOS 131. sprintf(infile, "%s.bas", RUMOR_FILE); 132. #else 133. sprintf(infile, "%s.base", RUMOR_FILE); 134. #endif 135. if(freopen(infile, RDMODE, stdin) == NULL) { 136. 137. perror(infile); 138. exit(1); 139. } 140. 141. while(gets(inline) != NULL) puts(inline); 142. 143. #ifdef KAA 144. sprintf(infile, "%s.kaa", RUMOR_FILE); 145. if(freopen(infile, RDMODE, stdin) == NULL) perror(infile); 146. 147. while(gets(inline) != NULL) puts(inline); 148. #endif 149. 150. #ifdef NEWCLASS 151. sprintf(infile, "%s.mrx", RUMOR_FILE); 152. if(freopen(infile, RDMODE, stdin) == NULL) perror(infile); 153. 154. while(gets(inline) != NULL) puts(inline); 155. #endif 156. fclose(stdin); 157. fclose(stdout); 158. } 159. 160. do_date(){ 161. int getpid(); 162. long clock, time(); 163. char tmpfile[30], cbuf[30], *c, *ctime(); 164. FILE *freopen(); 165. 166. sprintf(tmpfile, "makedefs.%d", getpid()); 167. if(freopen(tmpfile, WRMODE, stdout) == NULL) { 168. 169. perror(tmpfile); 170. exit(1); 171. } 172. if(freopen(DATE_FILE, RDMODE, stdin) == NULL) { 173. 174. perror(DATE_FILE); 175. exit(1); 176. } 177. 178. while(gets(inline) != NULL) { 179. 180. if(!strncmp(inline, "char datestring[] = ", 20)) break; 181. puts(inline); 182. } 183. time(&clock); 184. strcpy(cbuf, ctime(&clock)); 185. for(c = cbuf; *c != '\n'; c++); *c = 0; /* strip off the '\n' */ 186. printf("char datestring[] = %c%s%c;\n", '"', cbuf, '"'); 187. 188. fclose(stdin); 189. fclose(stdout); 190. #ifdef MSDOS 191. remove(DATE_FILE); 192. #endif 193. rename(tmpfile, DATE_FILE); 194. } 195. 196. do_data(){ 197. int getpid(); 198. char tmpfile[30]; 199. FILE *freopen(); 200. 201. sprintf(tmpfile, "%s.base", DATA_FILE); 202. if(freopen(tmpfile, RDMODE, stdin) == NULL) { 203. 204. perror(tmpfile); 205. exit(1); 206. } 207. if(freopen(DATA_FILE, WRMODE, stdout) == NULL) { 208. 209. perror(DATA_FILE); 210. exit(1); 211. } 212. 213. while(gets(inline) != NULL) { 214. #ifdef KOPS 215. if(!strcmp(inline, "K a kobold")) 216. printf("K\ta Keystone Kop\n"); 217. else 218. #endif 219. #ifdef KAA 220. if(!strcmp(inline, "Q a quasit")) 221. printf("Q\ta quantum mechanic\n"); 222. else 223. #endif 224. #ifdef ROCKMOLE 225. if(!strcmp(inline, "r a giant rat")) 226. printf("r\ta rockmole\n"); 227. else 228. #endif 229. #ifdef SPIDERS 230. if(!strcmp(inline, "s a scorpion")) 231. printf("s\ta giant spider\n"); 232. else if (!strcmp(inline, "\" an amulet")) 233. printf("\"\tan amulet (or a web)\n"); 234. else 235. #endif 236. #ifdef SPELLS 237. if (!strcmp(inline, "+ a door")) 238. printf("+\ta door (or a spell book)\n"); 239. else 240. #endif 241. #ifdef FOUNTAINS 242. if(!strcmp(inline, "} water filled area")) { 243. puts(inline); 244. printf("{\ta fountain\n"); 245. } else 246. #endif 247. #ifdef NEWCLASS 248. if(!strcmp(inline, "^ a trap")) { 249. puts(inline); 250. printf("\\\tan opulant throne.\n"); 251. } else 252. #endif 253. puts(inline); 254. } 255. #ifdef KAA 256. printf("9\ta giant\n"); 257. #endif 258. fclose(stdin); 259. fclose(stdout); 260. } 261. 262. #define LINSZ 1000 263. #define STRSZ 40 264. 265. int fd; 266. struct objdef { 267. 268. struct objdef *next; 269. char string[STRSZ]; 270. } *more, *current; 271. 272. do_objs(){ 273. register int index = 0; 274. register int propct = 0; 275. #ifdef SPELLS 276. register int nspell = 0; 277. #endif 278. FILE *freopen(); 279. register char *sp; 280. char *limit(); 281. int skip; 282. 283. fd = open(OBJ_FILE, 0); 284. if(fd < 0) { 285. perror(OBJ_FILE); 286. exit(1); 287. } 288. 289. if(freopen(ONAME_FILE, WRMODE, stdout) == NULL) { 290. perror(ONAME_FILE); 291. exit(1); 292. } 293. 294. current = 0; newobj(); 295. skipuntil("objects[] = {"); 296. 297. while(getentry(&skip)) { 298. if(!*(current->string)){ 299. if (skip) index++; 300. continue; 301. } 302. for(sp = current->string; *sp; sp++) 303. if(*sp == ' ' || *sp == '\t' || *sp == '-') 304. *sp = '_'; 305. 306. /* Do not process duplicates caused by #ifdef/#else pairs. */ 307. /* M. Stephenson */ 308. if (! duplicate()) { 309. 310. if(!strncmp(current->string, "RIN_", 4)) 311. specprop(current->string+4, propct++); 312. for(sp = current->string; *sp; sp++) capitalize(sp); 313. /* avoid trouble with stupid C preprocessors */ 314. if(!strncmp(current->string, "WORTHLESS_PIECE_OF_", 19)) 315. printf("/* #define\t%s\t%d */\n", current->string, index++); 316. else { 317. #ifdef SPELLS 318. if(!strncmp(current->string, "SPE_", 4)) nspell++; 319. printf("#define\t%s\t%d\n", limit(current->string), index++); 320. #else 321. if(strncmp(current->string, "SPE_", 4)) 322. printf("#define\t%s\t%d\n", limit(current->string), index++); 323. #endif 324. } 325. newobj(); 326. } 327. } 328. printf("\n#define CORPSE DEAD_HUMAN\n"); 329. #ifdef KOPS 330. printf("#define DEAD_KOP DEAD_KOBOLD\n"); 331. #endif 332. #ifdef SPIDERS 333. printf("#define DEAD_GIANT_SPIDER DEAD_GIANT_SCORPION\n"); 334. #endif 335. #ifdef ROCKMOLE 336. printf("#define DEAD_ROCKMOLE DEAD_GIANT_RAT\n"); 337. #endif 338. #ifndef KAA 339. printf("#define DEAD_QUASIT DEAD_QUANTUM_MECHANIC\n"); 340. printf("#define DEAD_VIOLET_FUNGI DEAD_VIOLET_FUNGUS\n"); 341. #endif 342. printf("#define LAST_GEM (JADE+1)\n"); 343. printf("#define LAST_RING %d\n", propct); 344. #ifdef SPELLS 345. printf("#define MAXSPELL %d\n", nspell+1); 346. #endif 347. printf("#define NROFOBJECTS %d\n", index-1); 348. exit(0); 349. } 350. 351. static char temp[32]; 352. 353. char * 354. limit(name) /* limit a name to 30 characters length */ 355. char *name; 356. { 357. strncpy(temp, name, 30); 358. temp[30] = 0; 359. return(temp); 360. } 361. 362. newobj() 363. { 364. extern long *alloc(); 365. 366. more = current; 367. current = (struct objdef *)alloc(sizeof(struct objdef)); 368. current->next = more; 369. } 370. 371. struct inherent { 372. 373. char *attrib, 374. *monsters; 375. } abilities[] = { "Regeneration", "TVi", 376. "See_invisible", "I", 377. "Poison_resistance", "abcghikqsuvxyADFQSVWXZ&", 378. "Fire_resistance", "gD&", 379. "Cold_resistance", "gFY", 380. "Teleportation", "LNt", 381. "Teleport_control", "t", 382. "", "" }; 383. 384. specprop(name, count) 385. 386. char *name; 387. int count; 388. { 389. int i; 390. char *tname, *limit(); 391. 392. tname = limit(name); 393. capitalize(tname); 394. for(i = 0; strlen(abilities[i].attrib); i++) 395. if(!strcmp(abilities[i].attrib, tname)) { 396. 397. printf("#define\tH%s\tu.uprops[%d].p_flgs\n", tname, count); 398. printf("#define\t%s\t((H%s) || index(\"%s\", u.usym))\n", 399. tname, tname, abilities[i].monsters); 400. return(0); 401. } 402. 403. printf("#define\t%s\tu.uprops[%d].p_flgs\n", tname, count); 404. return(0); 405. } 406. 407. char line[LINSZ], *lp = line, *lp0 = line, *lpe = line; 408. int xeof; 409. 410. readline(){ 411. register int n = read(fd, lp0, (line+LINSZ)-lp0); 412. if(n < 0){ 413. printf("Input error.\n"); 414. exit(1); 415. } 416. if(n == 0) xeof++; 417. lpe = lp0+n; 418. } 419. 420. char 421. nextchar(){ 422. if(lp == lpe){ 423. readline(); 424. lp = lp0; 425. } 426. return((lp == lpe) ? 0 : *lp++); 427. } 428. 429. skipuntil(s) char *s; { 430. register char *sp0, *sp1; 431. loop: 432. while(*s != nextchar()) 433. if(xeof) { 434. printf("Cannot skipuntil %s\n", s); 435. exit(1); 436. } 437. if(strlen(s) > lpe-lp+1){ 438. register char *lp1, *lp2; 439. lp2 = lp; 440. lp1 = lp = lp0; 441. while(lp2 != lpe) *lp1++ = *lp2++; 442. lp2 = lp0; /* save value */ 443. lp0 = lp1; 444. readline(); 445. lp0 = lp2; 446. if(strlen(s) > lpe-lp+1) { 447. printf("error in skipuntil"); 448. exit(1); 449. } 450. } 451. sp0 = s+1; 452. sp1 = lp; 453. while(*sp0 && *sp0 == *sp1) sp0++, sp1++; 454. if(!*sp0){ 455. lp = sp1; 456. return(1); 457. } 458. goto loop; 459. } 460. 461. getentry(skip) int *skip; { 462. int inbraces = 0, inparens = 0, stringseen = 0, commaseen = 0; 463. int prefix = 0; 464. char ch; 465. #define NSZ 10 466. char identif[NSZ], *ip; 467. current->string[0] = current->string[4] = 0; 468. /* read until {...} or XXX(...) followed by , 469. skip comment and #define lines 470. deliver 0 on failure 471. */ 472. while(1) { 473. ch = nextchar(); 474. swi: 475. if(letter(ch)){ 476. ip = identif; 477. do { 478. if(ip < identif+NSZ-1) *ip++ = ch; 479. ch = nextchar(); 480. } while(letter(ch) || digit(ch)); 481. *ip = 0; 482. while(ch == ' ' || ch == '\t') ch = nextchar(); 483. if(ch == '(' && !inparens && !stringseen) 484. if(!strcmp(identif, "WAND") || 485. !strcmp(identif, "RING") || 486. !strcmp(identif, "POTION") || 487. !strcmp(identif, "SPELL") || 488. !strcmp(identif, "SCROLL")) 489. (void) strncpy(current->string, identif, 3), 490. current->string[3] = '_', 491. prefix = 4; 492. } 493. switch(ch) { 494. case '/': 495. /* watch for comment */ 496. if((ch = nextchar()) == '*') 497. skipuntil("*/"); 498. goto swi; 499. case '{': 500. inbraces++; 501. continue; 502. case '(': 503. inparens++; 504. continue; 505. case '}': 506. inbraces--; 507. if(inbraces < 0) return(0); 508. continue; 509. case ')': 510. inparens--; 511. if(inparens < 0) { 512. printf("too many ) ?"); 513. exit(1); 514. } 515. continue; 516. case '\n': 517. /* watch for #define at begin of line */ 518. if((ch = nextchar()) == '#'){ 519. register char pch; 520. /* skip until '\n' not preceded by '\\' */ 521. do { 522. pch = ch; 523. ch = nextchar(); 524. } while(ch != '\n' || pch == '\\'); 525. continue; 526. } 527. goto swi; 528. case ',': 529. if(!inparens && !inbraces){ 530. if(prefix && !current->string[prefix]) { 531. #ifndef SPELLS 532. *skip = strncmp(current->string, "SPE_", 4); 533. #else 534. *skip = 1; 535. #endif 536. current->string[0] = 0; 537. } 538. if(stringseen) return(1); 539. printf("unexpected ,\n"); 540. exit(1); 541. } 542. commaseen++; 543. continue; 544. case '\: 545. if((ch = nextchar()) == '\\') ch = nextchar(); 546. if(nextchar() != '\){ 547. printf("strange character denotation?\n"); 548. exit(1); 549. } 550. continue; 551. case '"': 552. { 553. register char *sp = current->string + prefix; 554. register char pch; 555. register int store = (inbraces || inparens) 556. && !stringseen++ && !commaseen; 557. do { 558. pch = ch; 559. ch = nextchar(); 560. if(store && sp < current->string+STRSZ) 561. *sp++ = ch; 562. } while(ch != '"' || pch == '\\'); 563. if(store) *--sp = 0; 564. continue; 565. } 566. } 567. } 568. } 569. 570. duplicate() { 571. 572. char s[STRSZ]; 573. register char *c; 574. register struct objdef *testobj; 575. 576. strcpy (s, current->string); 577. for(c = s; *c != 0; c++) capitalize(c); 578. 579. for(testobj = more; testobj != 0; testobj = testobj->next) 580. if(! strcmp(s, testobj->string)) return(1); 581. 582. return(0); 583. } 584. 585. capitalize(sp) register char *sp; { 586. if('a' <= *sp && *sp <= 'z') *sp += 'A'-'a'; 587. } 588. 589. letter(ch) register char ch; { 590. return( ('a' <= ch && ch <= 'z') || 591. ('A' <= ch && ch <= 'Z') ); 592. } 593. 594. digit(ch) register char ch; { 595. return( '0' <= ch && ch <= '9' ); 596. } 597. 598. /* a copy of the panic code from hack.pri.c, edited for standalone use */ 599. 600. boolean panicking = 0; 601. 602. panic(str,a1,a2,a3,a4,a5,a6) 603. char *str; 604. { 605. if(panicking++) exit(1); /* avoid loops - this should never happen*/ 606. fputs(" ERROR: ", stdout); 607. printf(str,a1,a2,a3,a4,a5,a6); 608. #ifdef DEBUG 609. # ifdef UNIX 610. if(!fork()) 611. abort(); /* generate core dump */ 612. # endif 613. #endif 614. exit(1); 615. } 616. 617. #if defined(SYSV) || defined(GENIX) 618. rename(oldname, newname) 619. char *oldname, *newname; 620. { 621. if (strcmp(oldname, newname)) { 622. 623. unlink(newname); 624. link(oldname, newname); 625. unlink(oldname); 626. } 627. } 628. #endif 629. 630. #ifdef __TURBOC__ 631. int getpid() { 632. return(1); 633. } 634. #endif