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