summaryrefslogtreecommitdiff
path: root/mac.c
diff options
context:
space:
mode:
authorPatrick McCarty <patrick.mccarty@linux.intel.com>2013-04-12 10:40:25 -0700
committerPatrick McCarty <patrick.mccarty@linux.intel.com>2013-04-12 10:40:25 -0700
commit793eb3eb123664017100dfb1a5407f0da639a339 (patch)
tree2a6511443d115418007151f95f3a0fa8f5300974 /mac.c
downloadctags-793eb3eb123664017100dfb1a5407f0da639a339.tar.gz
ctags-793eb3eb123664017100dfb1a5407f0da639a339.tar.bz2
ctags-793eb3eb123664017100dfb1a5407f0da639a339.zip
Imported Upstream version 5.8upstream/5.8upstream
Diffstat (limited to 'mac.c')
-rw-r--r--mac.c273
1 files changed, 273 insertions, 0 deletions
diff --git a/mac.c b/mac.c
new file mode 100644
index 0000000..af4d16f
--- /dev/null
+++ b/mac.c
@@ -0,0 +1,273 @@
+/*
+* $Id: mac.c 443 2006-05-30 04:37:13Z darren $
+*
+* Copyright (c) 2001, Maarten L. Hekkelman
+*
+* Author: Maarten L. Hekkelman <maarten@hekkelman.com>
+* http://www.hekkelman.com
+*
+* This source code is released for free distribution under the terms of the
+* GNU General Public License. It is provided on an as-is basis and no
+* responsibility is accepted for its failure to perform as expected.
+*
+* This module contains support functions for Exuberant Ctags on Macintosh.
+*/
+
+/*
+* INCLUDE FILES
+*/
+#include "general.h"
+
+#include <Files.h>
+#include <TextUtils.h>
+#include <stdlib.h>
+#include <string.h>
+#include <stdio.h>
+
+/*
+* FUNCTION DEFINITIONS
+*/
+
+static int get_path(const char* in_unix_path, unsigned char* out_mac_path)
+{
+ int l = strlen(in_unix_path);
+ int result = 0;
+
+ if (l > 254)
+ result = -1;
+ else
+ {
+ const char* s = in_unix_path;
+ char *d = (char*)out_mac_path + 1;
+
+ if (*s != '/')
+ *d++ = ':';
+ else
+ ++s;
+
+ while (*s)
+ {
+ if (s[0] == '.' && s[1] == '.' && s[2] == '/')
+ {
+ s += 3;
+ *d++ = ':';
+ }
+ else if (s[0] == '.' && s[1] == '/')
+ s += 2;
+ else if (s[0] == '/')
+ {
+ *d++ = ':';
+
+ ++s;
+ while (*s == '/')
+ ++s;
+ }
+ else
+ *d++ = *s++;
+ }
+
+ out_mac_path[0] = (d - (char*)out_mac_path) - 1;
+ }
+
+ return result;
+}
+
+DIR *opendir(const char *dirname)
+{
+ DIR* dirp = (DIR*)calloc(1, sizeof(DIR));
+
+ if (dirp != NULL)
+ {
+ OSErr err;
+ Str255 s;
+ CInfoPBRec pb = { 0 };
+
+ if (strcmp(dirname, "."))
+ {
+ get_path(dirname, s);
+ pb.hFileInfo.ioNamePtr = s;
+ }
+ else
+ pb.hFileInfo.ioNamePtr = NULL;
+
+ err = PBGetCatInfoSync(&pb);
+ if (err != noErr || (pb.hFileInfo.ioFlAttrib & ioDirMask) == 0)
+ {
+ free(dirp);
+ dirp = NULL;
+ }
+ else
+ {
+ dirp->file.vRefNum = pb.hFileInfo.ioVRefNum;
+ dirp->file.parID = pb.hFileInfo.ioDirID;
+ dirp->file.name[0] = '\0';
+ dirp->index = 1;
+ }
+ }
+
+ return dirp;
+}
+
+struct dirent *readdir(DIR *dirp)
+{
+ if (dirp)
+ {
+ CInfoPBRec pb = { 0 };
+
+ pb.hFileInfo.ioVRefNum = dirp->file.vRefNum;
+ pb.hFileInfo.ioDirID = dirp->file.parID;
+ pb.hFileInfo.ioFDirIndex = dirp->index++;
+ pb.hFileInfo.ioNamePtr = dirp->file.name;
+
+ if (PBGetCatInfoSync(&pb) != noErr)
+ return NULL;
+
+ memcpy(dirp->ent.d_name, dirp->file.name + 1, dirp->file.name[0]);
+ dirp->ent.d_name[dirp->file.name[0]] = 0;
+ return &dirp->ent;
+ }
+ return NULL;
+}
+
+int closedir(DIR *dirp)
+{
+ if (dirp)
+ free(dirp);
+ return 0;
+}
+
+void rewinddir(DIR *dirp)
+{
+ if (dirp)
+ dirp->index = 1;
+}
+
+int mstat(const char* file, struct stat* st)
+{
+ CInfoPBRec pb;
+ unsigned char path[256];
+ int result = 0;
+
+ memset(&pb, 0, sizeof(CInfoPBRec));
+
+ if (strcmp(file, ".") == 0)
+ {
+ memset(st, 0, sizeof(struct stat));
+ st->st_mode = S_IFDIR;
+ st->st_ino = -1;
+ }
+ else
+ {
+ result = get_path(file, path);
+
+ if (result == 0)
+ {
+ pb.hFileInfo.ioNamePtr = path;
+
+ if (PBGetCatInfoSync(&pb) != noErr)
+ result = -1;
+ else
+ {
+ memset(st, 0, sizeof(struct stat));
+
+ if (pb.hFileInfo.ioFlAttrib & ioDirMask)
+ st->st_mode = S_IFDIR;
+ else
+ st->st_mode = S_IFREG;
+
+ st->st_ino = pb.hFileInfo.ioFlStBlk;
+ st->st_dev = pb.hFileInfo.ioVRefNum;
+ st->st_nlink = 1;
+ st->st_size = pb.hFileInfo.ioFlLgLen;
+ st->st_atime = pb.hFileInfo.ioFlMdDat;
+ st->st_mtime = pb.hFileInfo.ioFlMdDat;
+ st->st_ctime = pb.hFileInfo.ioFlCrDat;
+ }
+ }
+ }
+
+ return result;
+}
+
+#undef fopen
+
+FILE* mfopen(const char* file, const char* mode)
+{
+ unsigned char path[256];
+
+ if (get_path(file, path) == 0)
+ {
+ int l = path[0];
+ memmove(path, path + 1, l);
+ path[l] = 0;
+ return fopen((char*)path, mode);
+ }
+ else
+ return NULL;
+}
+
+char* getcwd(char* out_path, int out_path_len)
+{
+ OSErr err = noErr;
+ CInfoPBRec pb;
+ FSSpec cwd;
+
+ if (out_path == NULL)
+ {
+ if (out_path_len < PATH_MAX)
+ out_path_len = PATH_MAX;
+ out_path = (char*)malloc(out_path_len);
+ }
+
+ err = FSMakeFSSpec(0, 0, "\p:", &cwd);
+
+ if (cwd.parID == fsRtParID)
+ {
+ *out_path = '/';
+ memcpy(out_path + 1, cwd.name + 1, cwd.name[0]);
+ out_path[1 + cwd.name[0]] = 0;
+ }
+ else
+ {
+ /* The object isn't a volume */
+
+ /* Is the object a file or a directory? */
+
+ char t[PATH_MAX];
+ char* s;
+
+ s = t + PATH_MAX - cwd.name[0] - 1;
+ memcpy(s, cwd.name + 1, cwd.name[0]);
+ s[cwd.name[0]] = 0;
+
+ /* Get the ancestor directory names */
+ pb.dirInfo.ioNamePtr = cwd.name;
+ pb.dirInfo.ioVRefNum = cwd.vRefNum;
+ pb.dirInfo.ioDrParID = cwd.parID;
+ do /* loop until we have an error or find the root directory */
+ {
+ pb.dirInfo.ioFDirIndex = -1;
+ pb.dirInfo.ioDrDirID = pb.dirInfo.ioDrParID;
+ err = PBGetCatInfoSync(&pb);
+ if ( err == noErr )
+ {
+ *--s = '/';
+ s -= cwd.name[0];
+ memcpy(s, cwd.name + 1, cwd.name[0]);
+ }
+ }
+ while (err == noErr && pb.dirInfo.ioDrDirID != fsRtDirID && s > t + 1);
+
+ if (s > t + 1)
+ {
+ *--s = '/';
+ strcpy(out_path, s);
+ }
+ else
+ strcpy(out_path, ".");
+ }
+
+ return out_path;
+}
+
+/* vi:set tabstop=4 shiftwidth=4: */