Source:NetHack 1.3d/makedefs.c

From NetHackWiki
Revision as of 23:58, 3 March 2008 by Kernigh bot (talk | contribs) (NetHack 1.3d/makedefs.c moved to Source:NetHack 1.3d/makedefs.c: Robot: moved page)
(diff) ← Older revision | Latest revision (diff) | Newer revision → (diff)
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