Source:Hack 1.0/makedefs.c

From NetHackWiki
Jump to: navigation, search

Below is the full text to makedefs.c from the source code of Hack 1.0. To link to a particular line, write [[Hack 1.0/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.    /* construct definitions of object constants */
2.    #define	DEF_FILE	"def.objects.h"
3.    #define	LINSZ	1000
4.    #define	STRSZ	40
5.    
6.    int fd;
7.    char string[STRSZ];
8.    
9.    main(){
10.   register int index = 0;
11.   register int propct = 0;
12.   register char *sp;
13.   	fd = open(DEF_FILE, 0);
14.   	if(fd < 0) {
15.   		perror(DEF_FILE);
16.   		exit(1);
17.   	}
18.   	skipuntil("objects[] = {");
19.   	while(getentry()) {
20.   		if(!*string){
21.   			index++;
22.   			continue;
23.   		}
24.   		for(sp = string; *sp; sp++)
25.   			if(*sp == ' ' || *sp == '\t')
26.   				*sp = '_';
27.   		if(!strncmp(string, "RIN_", 4)){
28.   			capitalize(string+4);
29.   			printf("#define	%s	u.uprops[%d].p_flgs\n",
30.   				string+4, propct++);
31.   		}
32.   		for(sp = string; *sp; sp++) capitalize(sp);
33.   		/* avoid trouble with stupid C preprocessors */
34.   		if(!strncmp(string, "WORTHLESS_PIECE_OF_", 19))
35.   			printf("/* #define %s	%d */\n", string, index);
36.   		else
37.   			printf("#define	%s	%d\n", string, index);
38.   		index++;
39.   	}
40.   	printf("\n#define	CORPSE	DEAD_HUMAN\n");
41.   	printf("#define	LAST_GEM	(JADE+1)\n");
42.   	printf("#define	LAST_RING	%d\n", propct);
43.   	printf("#define	NROFOBJECTS	%d\n", index-1);
44.   }
45.   
46.   char line[LINSZ], *lp = line, *lp0 = line, *lpe = line;
47.   int eof;
48.   
49.   readline(){
50.   register int n = read(fd, lp0, (line+LINSZ)-lp0);
51.   	if(n < 0){
52.   		printf("Input error.\n");
53.   		exit(1);
54.   	}
55.   	if(n == 0) eof++;
56.   	lpe = lp0+n;
57.   }
58.   
59.   char
60.   nextchar(){
61.   	if(lp == lpe){
62.   		readline();
63.   		lp = lp0;
64.   	}
65.    return((lp == lpe) ? 0 : *lp++);
66.   }
67.   
68.   skipuntil(s) char *s; {
69.   register char *sp0, *sp1;
70.   loop:
71.   	while(*s != nextchar())
72.   		if(eof) {
73.   			printf("Cannot skipuntil %s\n", s);
74.   			exit(1);
75.   		}
76.   	if(strlen(s) > lpe-lp+1){
77.   		register char *lp1, *lp2;
78.   		lp2 = lp;
79.   		lp1 = lp = lp0;
80.   		while(lp2 != lpe) *lp1++ = *lp2++;
81.   		lp2 = lp0;	/* save value */
82.   		lp0 = lp1;
83.   		readline();
84.   		lp0 = lp2;
85.   		if(strlen(s) > lpe-lp+1) {
86.   			printf("error in skipuntil");
87.   			exit(1);
88.   		}
89.   	}
90.   	sp0 = s+1;
91.   	sp1 = lp;
92.   	while(*sp0 && *sp0 == *sp1) sp0++, sp1++;
93.   	if(!*sp0){
94.   		lp = sp1;
95.   		return(1);
96.   	}
97.    goto loop;
98.   }
99.   
100.  getentry(){
101.  int inbraces = 0, inparens = 0, stringseen = 0, commaseen = 0;
102.  int prefix = 0;
103.  char ch;
104.  #define	NSZ	10
105.  char identif[NSZ], *ip;
106.  	string[0] = string[4] = 0;
107.  	/* read until {...} or XXX(...) followed by ,
108.  	   skip comment and #define lines
109.  	   deliver 0 on failure
110.  	 */
111.  	while(1) {
112.  		ch = nextchar();
113.  	swi:
114.  		if(letter(ch)){
115.  			ip = identif;
116.  			do {
117.  				if(ip < identif+NSZ-1) *ip++ = ch;
118.  				ch = nextchar();
119.  			} while(letter(ch) || digit(ch));
120.  			*ip = 0;
121.  			while(ch == ' ' || ch == '\t') ch = nextchar();
122.  			if(ch == '(' && !inparens && !stringseen)
123.  				if(!strcmp(identif, "WAND") ||
124.  				   !strcmp(identif, "RING") ||
125.  				   !strcmp(identif, "POTION") ||
126.  				   !strcmp(identif, "SCROLL"))
127.  				(void) strncpy(string, identif, 3),
128.  				string[3] = '_',
129.  				prefix = 4;
130.  		}
131.  		switch(ch) {
132.  		case '/':
133.  			/* watch for comment */
134.  			if((ch = nextchar()) == '*')
135.  				skipuntil("*/");
136.  			goto swi;
137.  		case '{':
138.  			inbraces++;
139.  			continue;
140.  		case '(':
141.  			inparens++;
142.  			continue;
143.  		case '}':
144.  			inbraces--;
145.  			if(inbraces < 0) return(0);
146.  			continue;
147.  		case ')':
148.  			inparens--;
149.  			if(inparens < 0) {
150.  				printf("too many ) ?");
151.  				exit(1);
152.  			}
153.  			continue;
154.  		case '\n':
155.  			/* watch for #define at begin of line */
156.  			if((ch = nextchar()) == '#'){
157.  				register char pch;
158.  				/* skip until '\n' not preceded by '\\' */
159.  				do {
160.  					pch = ch;
161.  					ch = nextchar();
162.  				} while(ch != '\n' || pch == '\\');
163.  				continue;
164.  			}
165.  			goto swi;
166.  		case ',':
167.  			if(!inparens && !inbraces){
168.  				if(prefix && !string[prefix])
169.  					string[0] = 0;
170.  				if(stringseen) return(1);
171.  				printf("unexpected ,\n");
172.  				exit(1);
173.  			}
174.  			commaseen++;
175.  			continue;
176.  		case '\:
177.  			if((ch = nextchar()) == '\\') ch = nextchar();
178.  			if(nextchar() != '\){
179.  				printf("strange character denotation?\n");
180.  				exit(1);
181.  			}
182.  			continue;
183.  		case '"':
184.  			{
185.  				register char *sp = string + prefix;
186.  				register char pch;
187.  				register int store = (inbraces || inparens)
188.  					&& !stringseen++ && !commaseen;
189.  				do {
190.  					pch = ch;
191.  					ch = nextchar();
192.  					if(store && sp < string+STRSZ)
193.  						*sp++ = ch;
194.  				} while(ch != '"' || pch == '\\');
195.  				if(store) *--sp = 0;
196.  				continue;
197.  			}
198.  		}
199.  	}
200.  }
201.  
202.  capitalize(sp) register char *sp; {
203.  	if('a' <= *sp && *sp <= 'z') *sp += 'A'-'a';
204.  }
205.  
206.  letter(ch) register char ch; {
207.  	return( ('a' <= ch && ch <= 'z') ||
208.  		('A' <= ch && ch <= 'Z') );
209.  }
210.  
211.  digit(ch) register char ch; {
212.  	return( '0' <= ch && ch <= '9' );
213.  }