os/persistentdata/persistentstorage/sqlite3api/TEST/TCL/tcldistribution/mac/tclMacUnix.c
author sl
Tue, 10 Jun 2014 14:32:02 +0200
changeset 1 260cb5ec6c19
permissions -rw-r--r--
Update contrib.
sl@0
     1
/* 
sl@0
     2
 * tclMacUnix.c --
sl@0
     3
 *
sl@0
     4
 *	This file contains routines to implement several features
sl@0
     5
 *	available to the Unix implementation, but that require
sl@0
     6
 *      extra work to do on a Macintosh.  These include routines
sl@0
     7
 *      Unix Tcl normally hands off to the Unix OS.
sl@0
     8
 *
sl@0
     9
 * Copyright (c) 1993-1994 Lockheed Missle & Space Company, AI Center
sl@0
    10
 * Copyright (c) 1994-1997 Sun Microsystems, Inc.
sl@0
    11
 *
sl@0
    12
 * See the file "license.terms" for information on usage and redistribution
sl@0
    13
 * of this file, and for a DISCLAIMER OF ALL WARRANTIES.
sl@0
    14
 *
sl@0
    15
 * RCS: @(#) $Id: tclMacUnix.c,v 1.5 2002/10/09 11:54:45 das Exp $
sl@0
    16
 */
sl@0
    17
sl@0
    18
#include <Files.h>
sl@0
    19
#include <Strings.h>
sl@0
    20
#include <TextUtils.h>
sl@0
    21
#include <Finder.h>
sl@0
    22
#include <FSpCompat.h>
sl@0
    23
#include <Aliases.h>
sl@0
    24
#include <Errors.h>
sl@0
    25
sl@0
    26
#include "tclInt.h"
sl@0
    27
#include "tclMacInt.h"
sl@0
    28
sl@0
    29
/*
sl@0
    30
 * The following two Includes are from the More Files package
sl@0
    31
 */
sl@0
    32
#include "FileCopy.h"
sl@0
    33
#include "MoreFiles.h"
sl@0
    34
#include "MoreFilesExtras.h"
sl@0
    35
sl@0
    36
/*
sl@0
    37
 * The following may not be defined in some versions of
sl@0
    38
 * MPW header files.
sl@0
    39
 */
sl@0
    40
#ifndef kIsInvisible
sl@0
    41
#define kIsInvisible 0x4000
sl@0
    42
#endif
sl@0
    43
#ifndef kIsAlias
sl@0
    44
#define kIsAlias 0x8000
sl@0
    45
#endif
sl@0
    46
sl@0
    47
/*
sl@0
    48
 * Missing error codes
sl@0
    49
 */
sl@0
    50
#define usageErr		500
sl@0
    51
#define noSourceErr		501
sl@0
    52
#define isDirErr		502
sl@0
    53
sl@0
    54

sl@0
    55
/*
sl@0
    56
 *----------------------------------------------------------------------
sl@0
    57
 *
sl@0
    58
 * Tcl_EchoCmd --
sl@0
    59
 *
sl@0
    60
 *    Implements the TCL echo command:
sl@0
    61
 *        echo ?str ...?
sl@0
    62
 *
sl@0
    63
 * Results:
sl@0
    64
 *      Always returns TCL_OK.
sl@0
    65
 *
sl@0
    66
 * Side effects:
sl@0
    67
 *	None.
sl@0
    68
 *
sl@0
    69
 *----------------------------------------------------------------------
sl@0
    70
 */
sl@0
    71
sl@0
    72
int
sl@0
    73
Tcl_EchoCmd(
sl@0
    74
    ClientData dummy,			/* Not used. */
sl@0
    75
    Tcl_Interp *interp,			/* Current interpreter. */
sl@0
    76
    int argc,				/* Number of arguments. */
sl@0
    77
    CONST char **argv)			/* Argument strings. */
sl@0
    78
{
sl@0
    79
    Tcl_Channel chan;
sl@0
    80
    int mode, result, i;
sl@0
    81
sl@0
    82
    chan = Tcl_GetChannel(interp, "stdout", &mode);
sl@0
    83
    if (chan == (Tcl_Channel) NULL) {
sl@0
    84
        return TCL_ERROR;
sl@0
    85
    }
sl@0
    86
    for (i = 1; i < argc; i++) {
sl@0
    87
	result = Tcl_WriteChars(chan, argv[i], -1);
sl@0
    88
	if (result < 0) {
sl@0
    89
	    Tcl_AppendResult(interp, "echo: ", Tcl_GetChannelName(chan),
sl@0
    90
		    ": ", Tcl_PosixError(interp), (char *) NULL);
sl@0
    91
	    return TCL_ERROR;
sl@0
    92
	}
sl@0
    93
        if (i < (argc - 1)) {
sl@0
    94
	    Tcl_WriteChars(chan, " ", -1);
sl@0
    95
	}
sl@0
    96
    }
sl@0
    97
    Tcl_WriteChars(chan, "\n", -1);
sl@0
    98
    return TCL_OK;
sl@0
    99
}
sl@0
   100

sl@0
   101
/*
sl@0
   102
 *----------------------------------------------------------------------
sl@0
   103
 *
sl@0
   104
 * Tcl_LsObjCmd --
sl@0
   105
 *
sl@0
   106
 *	This procedure is invoked to process the "ls" Tcl command.
sl@0
   107
 *	See the user documentation for details on what it does.
sl@0
   108
 *
sl@0
   109
 * Results:
sl@0
   110
 *	A standard Tcl result.
sl@0
   111
 *
sl@0
   112
 * Side effects:
sl@0
   113
 *	See the user documentation.
sl@0
   114
 *
sl@0
   115
 *----------------------------------------------------------------------
sl@0
   116
 */
sl@0
   117
int
sl@0
   118
Tcl_LsObjCmd(
sl@0
   119
    ClientData dummy,			/* Not used. */
sl@0
   120
    Tcl_Interp *interp,			/* Current interpreter. */
sl@0
   121
    int objc,				/* Number of arguments. */
sl@0
   122
    Tcl_Obj *CONST objv[])		/* Argument strings. */
sl@0
   123
{
sl@0
   124
#define STRING_LENGTH 80
sl@0
   125
#define CR '\n'
sl@0
   126
    int i, j;
sl@0
   127
    int fieldLength, len = 0, maxLen = 0, perLine;
sl@0
   128
    OSErr err;
sl@0
   129
    CInfoPBRec paramBlock;
sl@0
   130
    HFileInfo *hpb = (HFileInfo *)&paramBlock;
sl@0
   131
    DirInfo *dpb = (DirInfo *)&paramBlock;
sl@0
   132
    char theFile[256];
sl@0
   133
    char theLine[STRING_LENGTH + 2];
sl@0
   134
    int fFlag = false, pFlag = false, aFlag = false, lFlag = false,
sl@0
   135
	cFlag = false, hFlag = false;
sl@0
   136
    char *argv;
sl@0
   137
    Tcl_Obj *newObjv[2], *resultObjPtr;
sl@0
   138
sl@0
   139
    /*
sl@0
   140
     * Process command flags.  End if argument doesn't start
sl@0
   141
     * with a dash or is a dash by itself.  The remaining arguments
sl@0
   142
     * should be files.
sl@0
   143
     */
sl@0
   144
    for (i = 1; i < objc; i++) {
sl@0
   145
    	argv = Tcl_GetString(objv[i]);
sl@0
   146
	if (argv[0] != '-') {
sl@0
   147
	    break;
sl@0
   148
	}
sl@0
   149
		
sl@0
   150
	if (!strcmp(argv, "-")) {
sl@0
   151
	    i++;
sl@0
   152
	    break;
sl@0
   153
	}
sl@0
   154
		
sl@0
   155
	for (j = 1 ; argv[j] ; ++j) {
sl@0
   156
	    switch(argv[j]) {
sl@0
   157
	    case 'a':
sl@0
   158
	    case 'A':
sl@0
   159
		aFlag = true;
sl@0
   160
		break;
sl@0
   161
	    case '1':
sl@0
   162
		cFlag = false;
sl@0
   163
		break;
sl@0
   164
	    case 'C':
sl@0
   165
		cFlag = true;
sl@0
   166
		break;
sl@0
   167
	    case 'F':
sl@0
   168
		fFlag = true;
sl@0
   169
		break;
sl@0
   170
	    case 'H':
sl@0
   171
		hFlag = true;
sl@0
   172
		break;
sl@0
   173
	    case 'p':
sl@0
   174
		pFlag = true;
sl@0
   175
		break;
sl@0
   176
	    case 'l':
sl@0
   177
		pFlag = false;
sl@0
   178
		lFlag = true;
sl@0
   179
		break;
sl@0
   180
	    default:
sl@0
   181
		Tcl_AppendResult(interp, "error - unknown flag ",
sl@0
   182
			"usage: ls -apCFHl1 ?files? ", NULL);
sl@0
   183
		return TCL_ERROR;
sl@0
   184
	    }
sl@0
   185
	}
sl@0
   186
    }
sl@0
   187
sl@0
   188
    objv += i;
sl@0
   189
    objc -= i;
sl@0
   190
sl@0
   191
    /*
sl@0
   192
     * No file specifications means we search for all files.
sl@0
   193
     * Glob will be doing most of the work.
sl@0
   194
     */
sl@0
   195
     if (!objc) {
sl@0
   196
	objc = 1;
sl@0
   197
	newObjv[0] = Tcl_NewStringObj("*", -1);
sl@0
   198
	newObjv[1] = NULL;
sl@0
   199
	objv = newObjv;
sl@0
   200
    }
sl@0
   201
sl@0
   202
    if (Tcl_GlobObjCmd(NULL, interp, objc + 1, objv - 1) != TCL_OK) {
sl@0
   203
    	Tcl_ResetResult(interp);
sl@0
   204
    	return TCL_ERROR;
sl@0
   205
    }
sl@0
   206
sl@0
   207
    resultObjPtr = Tcl_GetObjResult(interp);
sl@0
   208
    Tcl_IncrRefCount(resultObjPtr);
sl@0
   209
    if (Tcl_ListObjGetElements(interp, resultObjPtr, &objc, (Tcl_Obj ***)&objv) != TCL_OK) {
sl@0
   210
    	Tcl_DecrRefCount(resultObjPtr);
sl@0
   211
    	return TCL_ERROR;
sl@0
   212
    }
sl@0
   213
sl@0
   214
    Tcl_ResetResult(interp);
sl@0
   215
sl@0
   216
    /*
sl@0
   217
     * There are two major methods for listing files: the long
sl@0
   218
     * method and the normal method.
sl@0
   219
     */
sl@0
   220
    if (lFlag) {
sl@0
   221
	char	creator[5], type[5], time[16], date[16];
sl@0
   222
	char	lineTag;
sl@0
   223
	long	size;
sl@0
   224
	unsigned short flags;
sl@0
   225
	Tcl_Obj *objPtr;
sl@0
   226
	char *string;
sl@0
   227
	int length;
sl@0
   228
sl@0
   229
	/*
sl@0
   230
	 * Print the header for long listing.
sl@0
   231
	 */
sl@0
   232
	if (hFlag) {
sl@0
   233
	    sprintf(theLine, "T %7s %8s %8s %4s %4s %6s %s",
sl@0
   234
		    "Size", "ModTime", "ModDate",
sl@0
   235
		    "CRTR", "TYPE", "Flags", "Name");
sl@0
   236
	    Tcl_AppendResult(interp, theLine, "\n", NULL);
sl@0
   237
	    Tcl_AppendResult(interp,
sl@0
   238
		    "-------------------------------------------------------------\n",
sl@0
   239
		    NULL);
sl@0
   240
	}
sl@0
   241
		
sl@0
   242
	for (i = 0; i < objc; i++) {
sl@0
   243
	    strcpy(theFile, Tcl_GetString(objv[i]));
sl@0
   244
			
sl@0
   245
	    c2pstr(theFile);
sl@0
   246
	    hpb->ioCompletion = NULL;
sl@0
   247
	    hpb->ioVRefNum = 0;
sl@0
   248
	    hpb->ioFDirIndex = 0;
sl@0
   249
	    hpb->ioNamePtr = (StringPtr) theFile;
sl@0
   250
	    hpb->ioDirID = 0L;
sl@0
   251
	    err = PBGetCatInfoSync(&paramBlock);
sl@0
   252
	    p2cstr((StringPtr) theFile);
sl@0
   253
sl@0
   254
	    if (hpb->ioFlAttrib & 16) {
sl@0
   255
		/*
sl@0
   256
		 * For directories use zero as the size, use no Creator
sl@0
   257
		 * type, and use 'DIR ' as the file type.
sl@0
   258
		 */
sl@0
   259
		if ((aFlag == false) && (dpb->ioDrUsrWds.frFlags & 0x1000)) {
sl@0
   260
		    continue;
sl@0
   261
		}
sl@0
   262
		lineTag = 'D';
sl@0
   263
		size = 0;
sl@0
   264
		IUTimeString(dpb->ioDrMdDat, false, (unsigned char *)time);
sl@0
   265
		p2cstr((StringPtr)time);
sl@0
   266
		IUDateString(dpb->ioDrMdDat, shortDate, (unsigned char *)date);
sl@0
   267
		p2cstr((StringPtr)date);
sl@0
   268
		strcpy(creator, "    ");
sl@0
   269
		strcpy(type, "DIR ");
sl@0
   270
		flags = dpb->ioDrUsrWds.frFlags;
sl@0
   271
		if (fFlag || pFlag) {
sl@0
   272
		    strcat(theFile, ":");
sl@0
   273
		}
sl@0
   274
	    } else {
sl@0
   275
		/*
sl@0
   276
		 * All information for files should be printed.  This
sl@0
   277
		 * includes size, modtime, moddate, creator type, file
sl@0
   278
		 * type, flags, anf file name.
sl@0
   279
		 */
sl@0
   280
		if ((aFlag == false) &&
sl@0
   281
			(hpb->ioFlFndrInfo.fdFlags & kIsInvisible)) {
sl@0
   282
		    continue;
sl@0
   283
		}
sl@0
   284
		lineTag = 'F';
sl@0
   285
		size = hpb->ioFlLgLen + hpb->ioFlRLgLen;
sl@0
   286
		IUTimeString(hpb->ioFlMdDat, false, (unsigned char *)time);
sl@0
   287
		p2cstr((StringPtr)time);
sl@0
   288
		IUDateString(hpb->ioFlMdDat, shortDate, (unsigned char *)date);
sl@0
   289
		p2cstr((StringPtr)date);
sl@0
   290
		strncpy(creator, (char *) &hpb->ioFlFndrInfo.fdCreator, 4);
sl@0
   291
		creator[4] = 0;
sl@0
   292
		strncpy(type, (char *) &hpb->ioFlFndrInfo.fdType, 4);
sl@0
   293
		type[4] = 0;
sl@0
   294
		flags = hpb->ioFlFndrInfo.fdFlags;
sl@0
   295
		if (fFlag) {
sl@0
   296
		    if (hpb->ioFlFndrInfo.fdFlags & kIsAlias) {
sl@0
   297
			strcat(theFile, "@");
sl@0
   298
		    } else if (hpb->ioFlFndrInfo.fdType == 'APPL') {
sl@0
   299
			strcat(theFile, "*");
sl@0
   300
		    }
sl@0
   301
		}
sl@0
   302
	    }
sl@0
   303
			
sl@0
   304
	    sprintf(theLine, "%c %7ld %8s %8s %-4.4s %-4.4s 0x%4.4X %s",
sl@0
   305
		    lineTag, size, time, date, creator, type, flags, theFile);
sl@0
   306
						 
sl@0
   307
	    Tcl_AppendResult(interp, theLine, "\n", NULL);
sl@0
   308
	    
sl@0
   309
	}
sl@0
   310
		
sl@0
   311
	objPtr = Tcl_GetObjResult(interp);
sl@0
   312
	string = Tcl_GetStringFromObj(objPtr, &length);
sl@0
   313
	if ((length > 0) && (string[length - 1] == '\n')) {
sl@0
   314
	    Tcl_SetObjLength(objPtr, length - 1);
sl@0
   315
	}
sl@0
   316
    } else {
sl@0
   317
	/*
sl@0
   318
	 * Not in long format. We only print files names.  If the
sl@0
   319
	 * -C flag is set we need to print in multiple coloumns.
sl@0
   320
	 */
sl@0
   321
	int argCount, linePos;
sl@0
   322
	Boolean needNewLine = false;
sl@0
   323
sl@0
   324
	/*
sl@0
   325
	 * Fiend the field length: the length each string printed
sl@0
   326
	 * to the terminal will be.
sl@0
   327
	 */
sl@0
   328
	if (!cFlag) {
sl@0
   329
	    perLine = 1;
sl@0
   330
	    fieldLength = STRING_LENGTH;
sl@0
   331
	} else {
sl@0
   332
	    for (i = 0; i < objc; i++) {
sl@0
   333
	    	argv = Tcl_GetString(objv[i]);
sl@0
   334
		len = strlen(argv);
sl@0
   335
		if (len > maxLen) {
sl@0
   336
		    maxLen = len;
sl@0
   337
		}
sl@0
   338
	    }
sl@0
   339
	    fieldLength = maxLen + 3;
sl@0
   340
	    perLine = STRING_LENGTH / fieldLength;
sl@0
   341
	}
sl@0
   342
sl@0
   343
	argCount = 0;
sl@0
   344
	linePos = 0;
sl@0
   345
	memset(theLine, ' ', STRING_LENGTH);
sl@0
   346
	while (argCount < objc) {
sl@0
   347
	    strcpy(theFile, Tcl_GetString(objv[argCount]));
sl@0
   348
			
sl@0
   349
	    c2pstr(theFile);
sl@0
   350
	    hpb->ioCompletion = NULL;
sl@0
   351
	    hpb->ioVRefNum = 0;
sl@0
   352
	    hpb->ioFDirIndex = 0;
sl@0
   353
	    hpb->ioNamePtr = (StringPtr) theFile;
sl@0
   354
	    hpb->ioDirID = 0L;
sl@0
   355
	    err = PBGetCatInfoSync(&paramBlock);
sl@0
   356
	    p2cstr((StringPtr) theFile);
sl@0
   357
sl@0
   358
	    if (hpb->ioFlAttrib & 16) {
sl@0
   359
		/*
sl@0
   360
		 * Directory. If -a show hidden files.  If -f or -p
sl@0
   361
		 * denote that this is a directory.
sl@0
   362
		 */
sl@0
   363
		if ((aFlag == false) && (dpb->ioDrUsrWds.frFlags & 0x1000)) {
sl@0
   364
		    argCount++;
sl@0
   365
		    continue;
sl@0
   366
		}
sl@0
   367
		if (fFlag || pFlag) {
sl@0
   368
		    strcat(theFile, ":");
sl@0
   369
		}
sl@0
   370
	    } else {
sl@0
   371
		/*
sl@0
   372
		 * File: If -a show hidden files, if -f show links
sl@0
   373
		 * (aliases) and executables (APPLs).
sl@0
   374
		 */
sl@0
   375
		if ((aFlag == false) &&
sl@0
   376
			(hpb->ioFlFndrInfo.fdFlags & kIsInvisible)) {
sl@0
   377
		    argCount++;
sl@0
   378
		    continue;
sl@0
   379
		}
sl@0
   380
		if (fFlag) {
sl@0
   381
		    if (hpb->ioFlFndrInfo.fdFlags & kIsAlias) {
sl@0
   382
			strcat(theFile, "@");
sl@0
   383
		    } else if (hpb->ioFlFndrInfo.fdType == 'APPL') {
sl@0
   384
			strcat(theFile, "*");
sl@0
   385
		    }
sl@0
   386
		}
sl@0
   387
	    }
sl@0
   388
sl@0
   389
	    /*
sl@0
   390
	     * Print the item, taking into account multi-
sl@0
   391
	     * coloum output.
sl@0
   392
	     */
sl@0
   393
	    strncpy(theLine + (linePos * fieldLength), theFile,
sl@0
   394
		    strlen(theFile));
sl@0
   395
	    linePos++;
sl@0
   396
			
sl@0
   397
	    if (linePos == perLine) {
sl@0
   398
		theLine[STRING_LENGTH] = '\0';
sl@0
   399
		if (needNewLine) {
sl@0
   400
		    Tcl_AppendResult(interp, "\n", theLine, NULL);
sl@0
   401
		} else {
sl@0
   402
		    Tcl_AppendResult(interp, theLine, NULL);
sl@0
   403
		    needNewLine = true;
sl@0
   404
		}
sl@0
   405
		linePos = 0;
sl@0
   406
		memset(theLine, ' ', STRING_LENGTH);
sl@0
   407
	    }
sl@0
   408
			
sl@0
   409
	    argCount++;
sl@0
   410
	}
sl@0
   411
		
sl@0
   412
	if (linePos != 0) {
sl@0
   413
	    theLine[STRING_LENGTH] = '\0';
sl@0
   414
	    if (needNewLine) {
sl@0
   415
		Tcl_AppendResult(interp, "\n", theLine, NULL);
sl@0
   416
	    } else {
sl@0
   417
		Tcl_AppendResult(interp, theLine, NULL);
sl@0
   418
	    }
sl@0
   419
	}
sl@0
   420
    }
sl@0
   421
sl@0
   422
    Tcl_DecrRefCount(resultObjPtr);
sl@0
   423
    	
sl@0
   424
    return TCL_OK;
sl@0
   425
}