Source:NetHack 1.4f/makedefs.c

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

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	  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