Subversion Repositories planix.SVN

Rev

Rev 2 | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
2 - 1
#include "common.h"
2
 
3
/*
4
 *  WARNING!  This turns all upper case names into lower case
5
 *  local ones.
6
 */
7
 
8
/* predeclared */
9
static String	*getdbfiles(void);
10
static int	translate(char*, char**, String*, String*);
11
static int	lookup(String**, String*, String*);
12
static int	compare(String*, char*);
13
static char*	mklower(char*);
14
 
15
static int debug;
16
static int from;
17
static char *namefiles = "namefiles";
18
#define DEBUG if(debug)
19
 
20
/* loop through the names to be translated */
21
void
22
main(int argc, char *argv[])
23
{
24
	String *s;
25
	String *alias;		/* the alias for the name */
26
	char **names;		/* names of this system */
27
	String *files;		/* list of files to search */
28
	int i, rv;
29
	char *p;
30
 
31
	ARGBEGIN {
32
	case 'd':
33
		debug = 1;
34
		break;
35
	case 'f':
36
		from = 1;
37
		break;
38
	case 'n':
39
		namefiles = ARGF();
40
		break;
41
	} ARGEND
42
	if (chdir(UPASLIB) < 0) {
43
		perror("translate(chdir):");
44
		exit(1);
45
	}
46
 
47
	/* get environmental info */
48
	names = sysnames_read();
49
	files = getdbfiles();
50
	alias = s_new();
51
 
52
	/* loop through the names to be translated (from standard input) */
53
	for(i=0; i<argc; i++) {
54
		s = unescapespecial(s_copy(mklower(argv[i])));
55
		if(strchr(s_to_c(s), '!') == 0)
56
			rv = translate(s_to_c(s), names, files, alias);
57
		else
58
			rv = -1;
59
		if(from){
60
			if (rv >= 0 && *s_to_c(alias) != '\0'){
61
				p = strchr(s_to_c(alias), '\n');
62
				if(p)
63
					*p = 0;
64
				p = strchr(s_to_c(alias), '!');
65
				if(p) {
66
					*p = 0;
67
					print("%s", s_to_c(alias));
68
				} else {
69
					p = strchr(s_to_c(alias), '@');
70
					if(p)
71
						print("%s", p+1);
72
					else
73
						print("%s", s_to_c(alias));
74
				}
75
			}
76
		} else {
77
			if (rv < 0 || *s_to_c(alias) == '\0')
78
				print("local!%s\n", s_to_c(s));
79
			else {
80
				/* this must be a write, not a print */
81
				write(1, s_to_c(alias), strlen(s_to_c(alias)));
82
			}
83
		}
84
		s_free(s);
85
	}
86
	exits(0);
87
}
88
 
89
/* get the list of dbfiles to search */
90
static String *
91
getdbfiles(void)
92
{
93
	Sinstack *sp;
94
	String *files = s_new();
95
	char *nf;
96
 
97
	if(from)
98
		nf = "fromfiles";
99
	else
100
		nf = namefiles;
101
 
102
	/* system wide aliases */
103
	if ((sp = s_allocinstack(nf)) != 0){
104
		while(s_rdinstack(sp, files))
105
			s_append(files, " ");
106
		s_freeinstack(sp);
107
	}
108
 
109
 
110
	DEBUG print("files are %s\n", s_to_c(files));
111
 
112
	return files;
113
}
114
 
115
/* loop through the translation files */
116
static int
117
translate(char *name,		/* name to translate */
118
	char **namev,		/* names of this system */
119
	String *files,		/* names of system alias files */
120
	String *alias)		/* where to put the alias */
121
{
122
	String *file = s_new();
123
	String **fullnamev;
124
	int n, rv;
125
 
126
	rv = -1;
127
 
128
	DEBUG print("translate(%s, %s, %s)\n", name,
129
		s_to_c(files), s_to_c(alias));
130
 
131
	/* create the full name to avoid loops (system!name) */
132
	for(n = 0; namev[n]; n++)
133
		;
134
	fullnamev = (String**)malloc(sizeof(String*)*(n+2));
135
	n = 0;
136
	fullnamev[n++] = s_copy(name);
137
	for(; *namev; namev++){
138
		fullnamev[n] = s_copy(*namev);
139
		s_append(fullnamev[n], "!");
140
		s_append(fullnamev[n], name);
141
		n++;
142
	}
143
	fullnamev[n] = 0;
144
 
145
	/* look at system-wide names */
146
	s_restart(files);
147
	while (s_parse(files, s_restart(file)) != 0) {
148
		if (lookup(fullnamev, file, alias)==0) {
149
			rv = 0;
150
			goto out;
151
		}
152
	}
153
 
154
out:
155
	for(n = 0; fullnamev[n]; n++)
156
		s_free(fullnamev[n]);
157
	s_free(file);
158
	free(fullnamev);
159
	return rv;
160
}
161
 
162
/*
163
 *  very dumb conversion to bang format
164
 */
165
static String*
166
attobang(String *token)
167
{
168
	char *p;
169
	String *tok;
170
 
171
	p = strchr(s_to_c(token), '@');
172
	if(p == 0)
173
		return token;
174
 
175
	p++;
176
	tok = s_copy(p);
177
	s_append(tok, "!");
178
	s_nappend(tok, s_to_c(token), p - s_to_c(token) - 1);
179
 
180
	return tok;
181
}
182
 
183
/*  Loop through the entries in a translation file looking for a match.
184
 *  Return 0 if found, -1 otherwise.
185
 */
186
static int
187
lookup(
188
	String **namev,
189
	String *file,
190
	String *alias)	/* returned String */
191
{
192
	String *line = s_new();
193
	String *token = s_new();
194
	String *bangtoken;
195
	int i, rv = -1;
196
	char *name =  s_to_c(namev[0]);
197
	Sinstack *sp;
198
 
199
	DEBUG print("lookup(%s, %s, %s, %s)\n", s_to_c(namev[0]), s_to_c(namev[1]),
200
		s_to_c(file), s_to_c(alias));
201
 
202
	s_reset(alias);
203
	if ((sp = s_allocinstack(s_to_c(file))) == 0)
204
		return -1;
205
 
206
	/* look for a match */
207
	while (s_rdinstack(sp, s_restart(line))!=0) {
208
		DEBUG print("line is %s\n", s_to_c(line));
209
		s_restart(token);
210
		if (s_parse(s_restart(line), token)==0)
211
			continue;
212
		if (compare(token, "#include")==0){
213
			if(s_parse(line, s_restart(token))!=0) {
214
				if(lookup(namev, line, alias) == 0)
215
					break;
216
			}
217
			continue;
218
		}
219
		if (compare(token, name)!=0)
220
			continue;
221
		/* match found, get the alias */
222
		while(s_parse(line, s_restart(token))!=0) {
223
			bangtoken = attobang(token);
224
 
225
			/* avoid definition loops */
226
			for(i = 0; namev[i]; i++)
227
				if(compare(bangtoken, s_to_c(namev[i]))==0) {
228
					s_append(alias, "local");
229
					s_append(alias, "!");
230
					s_append(alias, name);
231
					break;
232
				}
233
 
234
			if(namev[i] == 0)
235
				s_append(alias, s_to_c(token));
236
			s_append(alias, "\n");
237
 
238
			if(bangtoken != token)
239
				s_free(bangtoken);
240
		}
241
		rv = 0;
242
		break;
243
	}
244
	s_free(line);
245
	s_free(token);
246
	s_freeinstack(sp);
247
	return rv;
248
}
249
 
250
#define lower(c) ((c)>='A' && (c)<='Z' ? (c)-('A'-'a'):(c))
251
 
252
/* compare two Strings (case insensitive) */
253
static int
254
compare(String *s1,
255
	char *p2)
256
{
257
	char *p1 = s_to_c(s1);
258
	int rv;
259
 
260
	DEBUG print("comparing %s to %s\n", p1, p2);
261
	while((rv = lower(*p1) - lower(*p2)) == 0) {
262
		if (*p1 == '\0')
263
			break;
264
		p1++;
265
		p2++;
266
	}
267
	return rv;
268
}
269
 
270
static char*
271
mklower(char *name)
272
{
273
	char *p;
274
	char c;
275
 
276
	for(p = name; *p; p++){
277
		c = *p;
278
		*p = lower(c);
279
	}
280
	return name;
281
}