Source:NetHack 2.2a/makedefs.c

From NetHackWiki
Jump to navigation Jump to search

Below is the full text to makedefs.c from the source code of NetHack 2.2a.

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