diff options
author | Patrick McCarty <patrick.mccarty@linux.intel.com> | 2013-04-12 10:40:25 -0700 |
---|---|---|
committer | Patrick McCarty <patrick.mccarty@linux.intel.com> | 2013-04-12 10:40:25 -0700 |
commit | 793eb3eb123664017100dfb1a5407f0da639a339 (patch) | |
tree | 2a6511443d115418007151f95f3a0fa8f5300974 /mac.c | |
download | ctags-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.c | 273 |
1 files changed, 273 insertions, 0 deletions
@@ -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: */ |