~ubuntu-branches/debian/sid/exuberant-ctags/sid

1 by Colin Watson
Import upstream version 5.5.4
1
/*
1.1.2 by Colin Watson
Import upstream version 5.7
2
*   $Id: mac.c 443 2006-05-30 04:37:13Z darren $
1 by Colin Watson
Import upstream version 5.5.4
3
*
4
*   Copyright (c) 2001, Maarten L. Hekkelman
5
*
6
*   Author: Maarten L. Hekkelman <maarten@hekkelman.com>
7
*           http://www.hekkelman.com
8
*
9
*   This source code is released for free distribution under the terms of the
10
*   GNU General Public License. It is provided on an as-is basis and no
11
*   responsibility is accepted for its failure to perform as expected.
12
*
13
*   This module contains support functions for Exuberant Ctags on Macintosh.
14
*/
15
16
/*
17
*   INCLUDE FILES
18
*/
19
#include "general.h"
20
21
#include <Files.h>
22
#include <TextUtils.h>
23
#include <stdlib.h>
24
#include <string.h>
25
#include <stdio.h>
26
27
/*
28
*   FUNCTION DEFINITIONS
29
*/
30
31
static int get_path(const char* in_unix_path, unsigned char* out_mac_path)
32
{
33
	int l = strlen(in_unix_path);
34
	int result = 0;
35
	
36
	if (l > 254)
37
		result = -1;
38
	else
39
	{
40
		const char* s = in_unix_path;
41
		char *d = (char*)out_mac_path + 1;
42
		
43
		if (*s != '/')
44
			*d++ = ':';
45
		else
46
			++s;
47
		
48
		while (*s)
49
		{
50
			if (s[0] == '.' && s[1] == '.' && s[2] == '/')
51
			{
52
				s += 3;
53
				*d++ = ':';
54
			}
55
			else if (s[0] == '.' && s[1] == '/')
56
				s += 2;
57
			else if (s[0] == '/')
58
			{
59
				*d++ = ':';
60
				
61
				++s;
62
				while (*s == '/')
63
					++s;
64
			}
65
			else
66
				*d++ = *s++;
67
		}
68
69
		out_mac_path[0] = (d - (char*)out_mac_path) - 1;
70
	}
71
	
72
	return result;
73
}
74
75
DIR *opendir(const char *dirname)
76
{
77
	DIR* dirp = (DIR*)calloc(1, sizeof(DIR));
78
79
	if (dirp != NULL)
80
	{
81
		OSErr err;
82
		Str255 s;
83
		CInfoPBRec pb = { 0 };
84
		
85
		if (strcmp(dirname, "."))
86
		{
87
			get_path(dirname, s);
88
			pb.hFileInfo.ioNamePtr = s;
89
		}
90
		else
91
			pb.hFileInfo.ioNamePtr = NULL;
92
		
93
		err = PBGetCatInfoSync(&pb);
94
		if (err != noErr || (pb.hFileInfo.ioFlAttrib & ioDirMask) == 0)
95
		{
96
			free(dirp);
97
			dirp = NULL;
98
		}
99
		else
100
		{
101
			dirp->file.vRefNum = pb.hFileInfo.ioVRefNum;
102
			dirp->file.parID = pb.hFileInfo.ioDirID;
103
			dirp->file.name[0] = '\0';
104
			dirp->index = 1;
105
		}
106
	}
107
	
108
	return dirp;
109
}
110
111
struct dirent *readdir(DIR *dirp)
112
{
113
	if (dirp)
114
	{
115
		CInfoPBRec pb = { 0 };
116
		
117
		pb.hFileInfo.ioVRefNum = dirp->file.vRefNum;
118
		pb.hFileInfo.ioDirID = dirp->file.parID;
119
		pb.hFileInfo.ioFDirIndex = dirp->index++;
120
		pb.hFileInfo.ioNamePtr = dirp->file.name;
121
	
122
		if (PBGetCatInfoSync(&pb) != noErr)
123
			return NULL;
124
		
125
		memcpy(dirp->ent.d_name, dirp->file.name + 1, dirp->file.name[0]);
126
		dirp->ent.d_name[dirp->file.name[0]] = 0;
127
		return &dirp->ent;
128
	}
129
	return NULL;
130
}
131
132
int closedir(DIR *dirp)
133
{
134
	if (dirp)
135
		free(dirp);
136
	return 0;
137
}
138
139
void rewinddir(DIR *dirp)
140
{
141
	if (dirp)
142
		dirp->index = 1;
143
}
144
145
int mstat(const char* file, struct stat* st)
146
{
147
	CInfoPBRec		pb;
148
	unsigned char	path[256];
149
	int				result = 0;
150
151
	memset(&pb, 0, sizeof(CInfoPBRec));
152
153
	if (strcmp(file, ".") == 0)
154
	{
155
		memset(st, 0, sizeof(struct stat));
156
		st->st_mode = S_IFDIR;
157
		st->st_ino = -1;
158
	}
159
	else
160
	{
161
		result = get_path(file, path);
162
		
163
		if (result == 0)
164
		{
165
			pb.hFileInfo.ioNamePtr = path;
166
			
167
			if (PBGetCatInfoSync(&pb) != noErr)
168
				result = -1;
169
			else
170
			{
171
				memset(st, 0, sizeof(struct stat));
172
	
173
				if (pb.hFileInfo.ioFlAttrib & ioDirMask)
174
					st->st_mode = S_IFDIR;
175
				else
176
					st->st_mode = S_IFREG;
177
178
				st->st_ino = pb.hFileInfo.ioFlStBlk;
179
				st->st_dev = pb.hFileInfo.ioVRefNum;
180
				st->st_nlink = 1;
181
				st->st_size = pb.hFileInfo.ioFlLgLen;
182
				st->st_atime = pb.hFileInfo.ioFlMdDat;
183
				st->st_mtime = pb.hFileInfo.ioFlMdDat;
184
				st->st_ctime = pb.hFileInfo.ioFlCrDat;
185
			}
186
		}
187
	}
188
189
	return result;
190
}
191
192
#undef fopen
193
194
FILE* mfopen(const char* file, const char* mode)
195
{
196
	unsigned char path[256];
197
		
198
	if (get_path(file, path) == 0)
199
	{
200
		int l = path[0];
201
		memmove(path, path + 1, l);
202
		path[l] = 0;
203
		return fopen((char*)path, mode);
204
	}
205
	else
206
		return NULL;
207
}
208
209
char* getcwd(char* out_path, int out_path_len)
210
{
211
	OSErr		err = noErr;
212
	CInfoPBRec	pb;
213
	FSSpec		cwd;
214
215
	if (out_path == NULL)
216
	{
217
		if (out_path_len < PATH_MAX)
218
			out_path_len = PATH_MAX;
219
		out_path = (char*)malloc(out_path_len);
220
	}
221
	
222
	err = FSMakeFSSpec(0, 0, "\p:", &cwd);
223
	
224
	if (cwd.parID == fsRtParID)
225
	{
226
		*out_path = '/';
227
		memcpy(out_path + 1, cwd.name + 1, cwd.name[0]);
228
		out_path[1 + cwd.name[0]] = 0;
229
	}
230
	else
231
	{
232
		/* The object isn't a volume */
233
		
234
		/* Is the object a file or a directory? */
235
		
236
		char t[PATH_MAX];
237
		char* s;
238
239
		s = t + PATH_MAX - cwd.name[0] - 1;
240
		memcpy(s, cwd.name + 1, cwd.name[0]);
241
		s[cwd.name[0]] = 0;
242
		
243
		/* Get the ancestor directory names */
244
		pb.dirInfo.ioNamePtr = cwd.name;
245
		pb.dirInfo.ioVRefNum = cwd.vRefNum;
246
		pb.dirInfo.ioDrParID = cwd.parID;
1.1.1 by Colin Watson
Import upstream version 5.6
247
		do  /* loop until we have an error or find the root directory */
1 by Colin Watson
Import upstream version 5.5.4
248
		{
249
			pb.dirInfo.ioFDirIndex = -1;
250
			pb.dirInfo.ioDrDirID = pb.dirInfo.ioDrParID;
251
			err = PBGetCatInfoSync(&pb);
252
			if ( err == noErr )
253
			{
254
				*--s = '/';
255
				s -= cwd.name[0];
256
				memcpy(s, cwd.name + 1, cwd.name[0]);
257
			}
258
		}
259
		while (err == noErr && pb.dirInfo.ioDrDirID != fsRtDirID && s > t + 1);
260
261
		if (s > t + 1)
262
		{
263
			*--s = '/';
264
			strcpy(out_path, s);
265
		}
266
		else
267
			strcpy(out_path, ".");
268
	}
269
270
	return out_path;
271
}
272
273
/* vi:set tabstop=4 shiftwidth=4: */