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: */
|