Source:NetHack 1.4f/makedefs.c

From NetHackWiki
Jump to: navigation, 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