summaryrefslogtreecommitdiffstats
path: root/macosx/tclMacOSXFCmd.c
diff options
context:
space:
mode:
Diffstat (limited to 'macosx/tclMacOSXFCmd.c')
-rw-r--r--macosx/tclMacOSXFCmd.c203
1 files changed, 173 insertions, 30 deletions
diff --git a/macosx/tclMacOSXFCmd.c b/macosx/tclMacOSXFCmd.c
index caa72a7..80e9785 100644
--- a/macosx/tclMacOSXFCmd.c
+++ b/macosx/tclMacOSXFCmd.c
@@ -5,12 +5,12 @@
* subcommands of the "file" command.
*
* Copyright (c) 2003 Tcl Core Team.
- * Copyright (c) 2003-2005 Daniel A. Steffen <das@users.sourceforge.net>
+ * Copyright (c) 2003-2006 Daniel A. Steffen <das@users.sourceforge.net>
*
* See the file "license.terms" for information on usage and redistribution of
* this file, and for a DISCLAIMER OF ALL WARRANTIES.
*
- * RCS: @(#) $Id: tclMacOSXFCmd.c,v 1.7 2005/11/27 06:09:10 das Exp $
+ * RCS: @(#) $Id: tclMacOSXFCmd.c,v 1.8 2006/03/21 11:06:23 das Exp $
*/
#include "tclInt.h"
@@ -57,9 +57,19 @@ enum {
typedef u_int32_t OSType;
-static int Tcl_GetOSTypeFromObj(Tcl_Interp *interp,
+static int GetOSTypeFromObj(Tcl_Interp *interp,
Tcl_Obj *objPtr, OSType *osTypePtr);
-static Tcl_Obj * Tcl_NewOSTypeStringObj(CONST OSType newOSType);
+static Tcl_Obj * NewOSTypeObj(CONST OSType newOSType);
+static int SetOSTypeFromAny(Tcl_Interp *interp, Tcl_Obj *objPtr);
+static void UpdateStringOfOSType(Tcl_Obj *objPtr);
+
+static Tcl_ObjType tclOSTypeType = {
+ "osType", /* name */
+ NULL, /* freeIntRepProc */
+ NULL, /* dupIntRepProc */
+ UpdateStringOfOSType, /* updateStringProc */
+ SetOSTypeFromAny /* setFromAnyProc */
+};
enum {
kIsInvisible = 0x4000,
@@ -152,11 +162,11 @@ TclMacOSXGetFileAttribute(
switch (objIndex) {
case MACOSX_CREATOR_ATTRIBUTE:
- *attributePtrPtr = Tcl_NewOSTypeStringObj(
+ *attributePtrPtr = NewOSTypeObj(
OSSwapBigToHostInt32(finder->creator));
break;
case MACOSX_TYPE_ATTRIBUTE:
- *attributePtrPtr = Tcl_NewOSTypeStringObj(
+ *attributePtrPtr = NewOSTypeObj(
OSSwapBigToHostInt32(finder->type));
break;
case MACOSX_HIDDEN_ATTRIBUTE:
@@ -248,13 +258,13 @@ TclMacOSXSetFileAttribute(
switch (objIndex) {
case MACOSX_CREATOR_ATTRIBUTE:
- if (Tcl_GetOSTypeFromObj(interp, attributePtr, &t) != TCL_OK) {
+ if (GetOSTypeFromObj(interp, attributePtr, &t) != TCL_OK) {
return TCL_ERROR;
}
finder->creator = OSSwapHostToBigInt32(t);
break;
case MACOSX_TYPE_ATTRIBUTE:
- if (Tcl_GetOSTypeFromObj(interp, attributePtr, &t) != TCL_OK) {
+ if (GetOSTypeFromObj(interp, attributePtr, &t) != TCL_OK) {
return TCL_ERROR;
}
finder->type = OSSwapHostToBigInt32(t);
@@ -359,7 +369,7 @@ TclMacOSXCopyFileAttributes(
if (copyfile(src, dst, NULL, COPYFILE_XATTR |
(S_ISLNK(statBufPtr->st_mode) ? COPYFILE_NOFOLLOW_SRC :
COPYFILE_ACL)) < 0) {
- return TCL_ERROR;
+ return TCL_ERROR;
}
return TCL_OK;
#elif defined(HAVE_GETATTRLIST)
@@ -426,7 +436,74 @@ TclMacOSXCopyFileAttributes(
/*
*----------------------------------------------------------------------
*
- * Tcl_GetOSTypeFromObj --
+ * TclMacOSXMatchType --
+ *
+ * This routine is used by the globbing code to check if a file
+ * matches a given mac type and/or creator code.
+ *
+ * Results:
+ * The return value is 1, 0 or -1 indicating whether the file
+ * matches the given criteria, does not match them, or an error
+ * occurred (in wich case an error is left in interp).
+ *
+ * Side effects:
+ * None.
+ *
+ *----------------------------------------------------------------------
+ */
+
+int
+TclMacOSXMatchType(
+ Tcl_Interp *interp, /* Interpreter to receive errors. */
+ CONST char *pathName, /* Native path to check. */
+ CONST char *fileName, /* Native filename to check. */
+ Tcl_StatBuf *statBufPtr, /* Stat info for file to check */
+ Tcl_GlobTypeData *types) /* Type description to match against. */
+{
+#ifdef HAVE_GETATTRLIST
+ struct attrlist alist;
+ fileinfobuf finfo;
+ finderinfo *finder = (finderinfo*)(&finfo.data);
+ OSType osType;
+
+ bzero(&alist, sizeof(struct attrlist));
+ alist.bitmapcount = ATTR_BIT_MAP_COUNT;
+ alist.commonattr = ATTR_CMN_FNDRINFO;
+ if (getattrlist(pathName, &alist, &finfo, sizeof(fileinfobuf), 0) != 0) {
+ return 0;
+ }
+ if ((types->perm & TCL_GLOB_PERM_HIDDEN) &&
+ !((finder->fdFlags & kFinfoIsInvisible) || (*fileName == '.'))) {
+ return 0;
+ }
+ if (S_ISDIR(statBufPtr->st_mode) && (types->macType || types->macCreator)) {
+ /* Directories don't support types or creators */
+ return 0;
+ }
+ if (types->macType) {
+ if (GetOSTypeFromObj(interp, types->macType, &osType) != TCL_OK) {
+ return -1;
+ }
+ if (osType != OSSwapBigToHostInt32(finder->type)) {
+ return 0;
+ }
+ }
+ if (types->macCreator) {
+ if (GetOSTypeFromObj(interp, types->macCreator, &osType) != TCL_OK) {
+ return -1;
+ }
+ if (osType != OSSwapBigToHostInt32(finder->creator)) {
+ return 0;
+ }
+ }
+#endif
+ return 1;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * GetOSTypeFromObj --
*
* Attempt to return an OSType from the Tcl object "objPtr".
*
@@ -441,11 +518,70 @@ TclMacOSXCopyFileAttributes(
*/
static int
-Tcl_GetOSTypeFromObj(
+GetOSTypeFromObj(
Tcl_Interp *interp, /* Used for error reporting if not NULL. */
Tcl_Obj *objPtr, /* The object from which to get an OSType. */
OSType *osTypePtr) /* Place to store resulting OSType. */
{
+ int result = TCL_OK;
+
+ if (objPtr->typePtr != &tclOSTypeType) {
+ result = tclOSTypeType.setFromAnyProc(interp, objPtr);
+ };
+ *osTypePtr = (OSType) objPtr->internalRep.longValue;
+ return result;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * NewOSTypeObj --
+ *
+ * Create a new OSType object.
+ *
+ * Results:
+ * The newly created OSType object is returned, it has ref count 0.
+ *
+ * Side effects:
+ * None.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static Tcl_Obj *
+NewOSTypeObj(
+ CONST OSType osType) /* OSType used to initialize the new object. */
+{
+ Tcl_Obj *objPtr;
+
+ TclNewObj(objPtr);
+ Tcl_InvalidateStringRep(objPtr);
+ objPtr->internalRep.longValue = (long) osType;
+ objPtr->typePtr = &tclOSTypeType;
+ return objPtr;
+}
+
+/*
+ *----------------------------------------------------------------------
+ *
+ * SetOSTypeFromAny --
+ *
+ * Attempts to force the internal representation for a Tcl object to
+ * tclOSTypeType, specifically.
+ *
+ * Results:
+ * The return value is a standard object Tcl result. If an error occurs
+ * during conversion, an error message is left in the interpreter's
+ * result unless "interp" is NULL.
+ *
+ *----------------------------------------------------------------------
+ */
+
+static int
+SetOSTypeFromAny(
+ Tcl_Interp *interp, /* Tcl interpreter */
+ Tcl_Obj *objPtr) /* Pointer to the object to convert */
+{
char *string;
int length, result = TCL_OK;
Tcl_DString ds;
@@ -459,13 +595,17 @@ Tcl_GetOSTypeFromObj(
string, "\": ", NULL);
result = TCL_ERROR;
} else {
+ OSType osType;
char string[4] = {'\0','\0','\0','\0'};
memcpy(string, Tcl_DStringValue(&ds),
(size_t) Tcl_DStringLength(&ds));
- *osTypePtr = (OSType) string[0] << 24 |
- (OSType) string[1] << 16 |
- (OSType) string[2] << 8 |
- (OSType) string[3];
+ osType = (OSType) string[0] << 24 |
+ (OSType) string[1] << 16 |
+ (OSType) string[2] << 8 |
+ (OSType) string[3];
+ TclFreeIntRep(objPtr);
+ objPtr->internalRep.longValue = (long) osType;
+ objPtr->typePtr = &tclOSTypeType;
}
Tcl_DStringFree(&ds);
Tcl_FreeEncoding(encoding);
@@ -475,39 +615,42 @@ Tcl_GetOSTypeFromObj(
/*
*----------------------------------------------------------------------
*
- * Tcl_NewOSTypeStringObj --
+ * UpdateStringOfOSType --
*
- * Create a new OSType string object.
+ * Update the string representation for an OSType object. Note: This
+ * function does not free an existing old string rep so storage will be
+ * lost if this has not already been done.
*
* Results:
- * The newly created string object is returned, it has ref count 0.
+ * None.
*
* Side effects:
- * None.
+ * The object's string is set to a valid string that results from the
+ * OSType-to-string conversion.
*
*----------------------------------------------------------------------
*/
-static Tcl_Obj *
-Tcl_NewOSTypeStringObj(
- CONST OSType newOSType) /* OSType used to initialize the new object. */
+static void
+UpdateStringOfOSType(
+ register Tcl_Obj *objPtr) /* OSType object whose string rep to update. */
{
char string[5];
- Tcl_Obj *resultPtr;
+ OSType osType = (OSType) objPtr->internalRep.longValue;
Tcl_DString ds;
Tcl_Encoding encoding = Tcl_GetEncoding(NULL, "macRoman");
- string[0] = (char) (newOSType >> 24);
- string[1] = (char) (newOSType >> 16);
- string[2] = (char) (newOSType >> 8);
- string[3] = (char) (newOSType);
+ string[0] = (char) (osType >> 24);
+ string[1] = (char) (osType >> 16);
+ string[2] = (char) (osType >> 8);
+ string[3] = (char) (osType);
string[4] = '\0';
Tcl_ExternalToUtfDString(encoding, string, -1, &ds);
- resultPtr = Tcl_NewStringObj(Tcl_DStringValue(&ds),
- Tcl_DStringLength(&ds));
+ objPtr->bytes = ckalloc((unsigned) Tcl_DStringLength(&ds) + 1);
+ strcpy(objPtr->bytes, Tcl_DStringValue(&ds));
+ objPtr->length = Tcl_DStringLength(&ds);
Tcl_DStringFree(&ds);
Tcl_FreeEncoding(encoding);
- return resultPtr;
}
/*