Making "inline" behave like an attribute. Fixes #1
[arduino-ctags.git] / mac.c
blobaf4d16f927f7adf1e37720703fd7d79a8557b8be
1 /*
2 * $Id: mac.c 443 2006-05-30 04:37:13Z darren $
4 * Copyright (c) 2001, Maarten L. Hekkelman
6 * Author: Maarten L. Hekkelman <maarten@hekkelman.com>
7 * http://www.hekkelman.com
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.
13 * This module contains support functions for Exuberant Ctags on Macintosh.
17 * INCLUDE FILES
19 #include "general.h"
21 #include <Files.h>
22 #include <TextUtils.h>
23 #include <stdlib.h>
24 #include <string.h>
25 #include <stdio.h>
28 * FUNCTION DEFINITIONS
31 static int get_path(const char* in_unix_path, unsigned char* out_mac_path)
33 int l = strlen(in_unix_path);
34 int result = 0;
36 if (l > 254)
37 result = -1;
38 else
40 const char* s = in_unix_path;
41 char *d = (char*)out_mac_path + 1;
43 if (*s != '/')
44 *d++ = ':';
45 else
46 ++s;
48 while (*s)
50 if (s[0] == '.' && s[1] == '.' && s[2] == '/')
52 s += 3;
53 *d++ = ':';
55 else if (s[0] == '.' && s[1] == '/')
56 s += 2;
57 else if (s[0] == '/')
59 *d++ = ':';
61 ++s;
62 while (*s == '/')
63 ++s;
65 else
66 *d++ = *s++;
69 out_mac_path[0] = (d - (char*)out_mac_path) - 1;
72 return result;
75 DIR *opendir(const char *dirname)
77 DIR* dirp = (DIR*)calloc(1, sizeof(DIR));
79 if (dirp != NULL)
81 OSErr err;
82 Str255 s;
83 CInfoPBRec pb = { 0 };
85 if (strcmp(dirname, "."))
87 get_path(dirname, s);
88 pb.hFileInfo.ioNamePtr = s;
90 else
91 pb.hFileInfo.ioNamePtr = NULL;
93 err = PBGetCatInfoSync(&pb);
94 if (err != noErr || (pb.hFileInfo.ioFlAttrib & ioDirMask) == 0)
96 free(dirp);
97 dirp = NULL;
99 else
101 dirp->file.vRefNum = pb.hFileInfo.ioVRefNum;
102 dirp->file.parID = pb.hFileInfo.ioDirID;
103 dirp->file.name[0] = '\0';
104 dirp->index = 1;
108 return dirp;
111 struct dirent *readdir(DIR *dirp)
113 if (dirp)
115 CInfoPBRec pb = { 0 };
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;
122 if (PBGetCatInfoSync(&pb) != noErr)
123 return NULL;
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;
129 return NULL;
132 int closedir(DIR *dirp)
134 if (dirp)
135 free(dirp);
136 return 0;
139 void rewinddir(DIR *dirp)
141 if (dirp)
142 dirp->index = 1;
145 int mstat(const char* file, struct stat* st)
147 CInfoPBRec pb;
148 unsigned char path[256];
149 int result = 0;
151 memset(&pb, 0, sizeof(CInfoPBRec));
153 if (strcmp(file, ".") == 0)
155 memset(st, 0, sizeof(struct stat));
156 st->st_mode = S_IFDIR;
157 st->st_ino = -1;
159 else
161 result = get_path(file, path);
163 if (result == 0)
165 pb.hFileInfo.ioNamePtr = path;
167 if (PBGetCatInfoSync(&pb) != noErr)
168 result = -1;
169 else
171 memset(st, 0, sizeof(struct stat));
173 if (pb.hFileInfo.ioFlAttrib & ioDirMask)
174 st->st_mode = S_IFDIR;
175 else
176 st->st_mode = S_IFREG;
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;
189 return result;
192 #undef fopen
194 FILE* mfopen(const char* file, const char* mode)
196 unsigned char path[256];
198 if (get_path(file, path) == 0)
200 int l = path[0];
201 memmove(path, path + 1, l);
202 path[l] = 0;
203 return fopen((char*)path, mode);
205 else
206 return NULL;
209 char* getcwd(char* out_path, int out_path_len)
211 OSErr err = noErr;
212 CInfoPBRec pb;
213 FSSpec cwd;
215 if (out_path == NULL)
217 if (out_path_len < PATH_MAX)
218 out_path_len = PATH_MAX;
219 out_path = (char*)malloc(out_path_len);
222 err = FSMakeFSSpec(0, 0, "\p:", &cwd);
224 if (cwd.parID == fsRtParID)
226 *out_path = '/';
227 memcpy(out_path + 1, cwd.name + 1, cwd.name[0]);
228 out_path[1 + cwd.name[0]] = 0;
230 else
232 /* The object isn't a volume */
234 /* Is the object a file or a directory? */
236 char t[PATH_MAX];
237 char* s;
239 s = t + PATH_MAX - cwd.name[0] - 1;
240 memcpy(s, cwd.name + 1, cwd.name[0]);
241 s[cwd.name[0]] = 0;
243 /* Get the ancestor directory names */
244 pb.dirInfo.ioNamePtr = cwd.name;
245 pb.dirInfo.ioVRefNum = cwd.vRefNum;
246 pb.dirInfo.ioDrParID = cwd.parID;
247 do /* loop until we have an error or find the root directory */
249 pb.dirInfo.ioFDirIndex = -1;
250 pb.dirInfo.ioDrDirID = pb.dirInfo.ioDrParID;
251 err = PBGetCatInfoSync(&pb);
252 if ( err == noErr )
254 *--s = '/';
255 s -= cwd.name[0];
256 memcpy(s, cwd.name + 1, cwd.name[0]);
259 while (err == noErr && pb.dirInfo.ioDrDirID != fsRtDirID && s > t + 1);
261 if (s > t + 1)
263 *--s = '/';
264 strcpy(out_path, s);
266 else
267 strcpy(out_path, ".");
270 return out_path;
273 /* vi:set tabstop=4 shiftwidth=4: */