mirror of
https://github.com/gnustep/libs-base.git
synced 2025-04-22 16:33:29 +00:00
Fixes from Frith-MacDonald.
git-svn-id: svn+ssh://svn.gna.org/svn/gnustep/libs/base/trunk@2701 72102866-910b-0410-8b05-ffd578937521
This commit is contained in:
parent
9fb3552e61
commit
793a5e1a62
31 changed files with 2483 additions and 406 deletions
96
ChangeLog
96
ChangeLog
|
@ -1,3 +1,99 @@
|
|||
Wed Jan 7 20:25:00 1997 Richard Frith-Macdonald <richard@brainstorm.co.uk>
|
||||
|
||||
* Tools/GNUmakefile: Added defaults.m
|
||||
|
||||
* Tools/defaults.m: New file defaults.m - command line tool like the
|
||||
OPENSTEP defaults command. Renders dread, dwrite and dremove obsolete.
|
||||
|
||||
* Tools/dread.m: Added -u flag and made numerous bug fixes.
|
||||
|
||||
* Tools/dremove.m: Added -u flag and made numerous bug fixes.
|
||||
|
||||
* Tools/dwrite.m: Added -u flag and made numerous bug fixes.
|
||||
|
||||
* checks/nsdate.m: Added some year-2000 tests.
|
||||
|
||||
* src/Dictionary.m: Removed ([-descriptionWithIndent:]) and the
|
||||
([-description]) methods - no longer needed for property lists.
|
||||
|
||||
* src/Heap.m: Added implementation of ([-minObject]) to take
|
||||
advantage of the known ordering of a heap - fixes performance
|
||||
problem with large numbers of timers in NSRunLoop.
|
||||
|
||||
* src/NSArray.m: Implemented many new methods for OPENSTEP -
|
||||
([+arrayWithArray:]), ([+arrayWithContentsOfFile:]),
|
||||
([+arrayWithObjects:count:]), ([-getObjects:]),
|
||||
([-getObjects:range:]), ([-indexOfObjectIdenticalto:inRange:]),
|
||||
([-indexOfObject:inRange:]), ([-makeObjectsPerformSelector:]),
|
||||
([-makeObjectsPerformSelector:withObject:]), ([-sortedArrayHint]),
|
||||
([-sortedArrayUsingFunction:context:hint:]),
|
||||
([-pathsMatchingExtensions:]), ([-descriptionWithLocale:]),
|
||||
([-descriptionWithLocale:indent:),
|
||||
([-replaceObjectsInRange:withObjectsFromArray:]),
|
||||
([-initWithContentsOfFile:]), ([-removeObject:inRange:]),
|
||||
([-removeObjectIdenticalTo:inRange:]), ([-removeObjectsInRange:])
|
||||
Modified ([-makeObjectsPerform:]) and
|
||||
([-makeObjectsPerform:wihtObject:]) to iterate through array in
|
||||
reverse as specified in OPENSTEP docs.
|
||||
Removed obsolete method - ([-descriptionWithIndent:])
|
||||
|
||||
* src/NSArray.m: Implemented new methods for OPENSTEP -
|
||||
([+dataWithData:]), ([-setData:])
|
||||
Modified ([-description]) to give tidier output.
|
||||
|
||||
* src/NSData.m: Implemented new methods for OPENSTEP -
|
||||
([+dataWithData:]), ([-setData:])
|
||||
Modified ([-description]) to give tidier output.
|
||||
|
||||
* src/NSDictionary.m: Implemented new methods for OPENSTEP -
|
||||
([-keysSortedByValueUsingSelector:]),
|
||||
([-objectsForKeys:notFoundMarker:]), ([-description]),
|
||||
([-descriptionInStringsFileFormat]), ([-descriptionWithLocale:]),
|
||||
([-descriptionWithLocale:indent:]), ([-setDictionary:]),
|
||||
|
||||
* src/NSFileHandle.m: Added extensions for getting information
|
||||
about sockets used in file handles.
|
||||
|
||||
* src/NSString.m: Removed ([-quotedCString]) and added new method
|
||||
([-descriptionForPropertyList]) to do things more neatly.
|
||||
|
||||
* src/NSTask.m: Added this OPENSTEP/Rhapsody class.
|
||||
|
||||
* src/TcpPort.m: Added check for bad data arriving on descriptor
|
||||
in ([-_tryToGetPacketFromReadableFD:])
|
||||
|
||||
* src/UnixFileHandle.m: Added stuff for getting information
|
||||
about sockets used in file handles.
|
||||
|
||||
* src/include/IndexedCollecting.h: Made 'IndexRange' a synonym for
|
||||
NSRange.
|
||||
|
||||
* src/include/NSArray.h: Changes to reflect the changes in methods
|
||||
implemented in NSArray.m
|
||||
|
||||
* src/include/NSData.h: Changes to reflect the changes in methods
|
||||
implemented in NSData.m
|
||||
|
||||
* src/include/NSDictionary.h: Changes to reflect the changes in methods
|
||||
implemented in NSData.m
|
||||
|
||||
* src/include/NSFileHandle.h: Changes to reflect the changes in methods
|
||||
implemented in NSFileHandle.m
|
||||
|
||||
* src/include/NSString.h: Changes to reflect the changes in methods
|
||||
implemented in NSString.m
|
||||
|
||||
* src/NSTask.h: Added this OPENSTEP/Rhapsody class.
|
||||
|
||||
* src/include/UnixFileHandle.h: Changes to reflect the changes in
|
||||
methods implemented in UnixFileHandle.m
|
||||
|
||||
* src/proplist.y: Make parsing less strict - permit dictionaries
|
||||
with or without a semicolon after the last key-value pair.
|
||||
|
||||
* src/stringsfile.y: Fixed bug in parser - it is legitimate to have
|
||||
a key-value pair without a value - in which case the '=' is omitted.
|
||||
|
||||
Fri Jan 9 10:04:09 1998 Adam Fedor <fedor@doc.com>
|
||||
|
||||
* Version: Release 0.4.0.
|
||||
|
|
|
@ -27,7 +27,7 @@ distribution.
|
|||
@section Where can you get it? How can you compile it?
|
||||
|
||||
@ifset GNUSTEP-BASE-FTP-MACHINE
|
||||
The libgnustep-base-@value{GNUSTEP-BASE-VERSION}.tar.gz distribution file has
|
||||
The gstepbase-@value{GNUSTEP-BASE-VERSION}.tar.gz distribution file has
|
||||
been placed on @samp{@value{GNUSTEP-BASE-FTP-MACHINE}} in
|
||||
@samp{@value{GNUSTEP-BASE-FTP-DIRECTORY}}.
|
||||
@end ifset
|
||||
|
|
|
@ -3,9 +3,6 @@
|
|||
@c This file uses the special commands @url{} and @email{}. They are
|
||||
@c handled by the doc/Makefile.
|
||||
|
||||
@setfilename GNUstep-FAQ.info
|
||||
@settitle GNUstep Frequently Asked Questions with Answers
|
||||
|
||||
@iftex
|
||||
@global@let@email=@i
|
||||
@global@let@url=@samp
|
||||
|
|
|
@ -37,11 +37,9 @@
|
|||
|
||||
#include <gnustep/base/preface.h>
|
||||
#include <gnustep/base/Collecting.h>
|
||||
#include <Foundation/NSRange.h>
|
||||
|
||||
typedef struct _IndexRange {
|
||||
unsigned location;
|
||||
unsigned length;
|
||||
} IndexRange;
|
||||
#define IndexRange NSRange
|
||||
|
||||
#define IndexRangeInside(RANGE1,RANGE2) \
|
||||
({IndexRange __a=(RANGE1), __b=(RANGE2); \
|
||||
|
|
|
@ -40,33 +40,54 @@
|
|||
@interface NSArray (NonCore) <NSCopying, NSMutableCopying>
|
||||
|
||||
+ array;
|
||||
+ arrayWithArray: (NSArray*)array;
|
||||
+ arrayWithContentsOfFile: (NSString*)file;
|
||||
+ arrayWithObject: anObject;
|
||||
+ arrayWithObjects: firstObj, ...;
|
||||
+ arrayWithObjects: (id*)objects count: (unsigned)count;
|
||||
- (NSArray*) arrayByAddingObject: anObject;
|
||||
- (NSArray*) arrayByAddingObjectsFromArray: (NSArray*)anotherArray;
|
||||
- initWithObjects: firstObj, ...;
|
||||
- initWithArray: (NSArray*)array;
|
||||
- initWithContentsOfFile: (NSString*)file;
|
||||
- initWithObjects: firstObj, ...;
|
||||
- inttWithObjects: (id*)objects count: (unsigned)count;
|
||||
|
||||
- (unsigned) indexOfObjectIdenticalTo: anObject;
|
||||
- (unsigned) indexOfObject: anObject;
|
||||
- (BOOL) containsObject: anObject;
|
||||
- (BOOL) isEqualToArray: (NSArray*)otherArray;
|
||||
- (void) getObjects: (id*)objs;
|
||||
- (void) getObjects: (id*)objs range: (NSRange)aRange;
|
||||
- (unsigned) indexOfObject: anObject;
|
||||
- (unsigned) indexOfObject: anObject inRange: (NSRange*)aRange;
|
||||
- (unsigned) indexOfObjectIdenticalTo: anObject;
|
||||
- (unsigned) indexOfObjectIdenticalTo: anObject inRange: (NSRange)aRange;
|
||||
- lastObject;
|
||||
|
||||
- firstObjectCommonWithArray: (NSArray*) otherArray;
|
||||
- (BOOL) isEqualToArray: (NSArray*)otherArray;
|
||||
|
||||
- (void) makeObjectsPerform: (SEL) aSelector;
|
||||
- (void) makeObjectsPerform: (SEL)aSelector withObject: argument;
|
||||
- (void) makeObjectsPerformSelector: (SEL) aSelector;
|
||||
- (void) makeObjectsPerformSelector: (SEL)aSelector withObject: argument;
|
||||
|
||||
- (NSArray*) sortedArrayUsingSelector: (SEL)comparator;
|
||||
- (NSData*) sortedArrayHint;
|
||||
- (NSArray*) sortedArrayUsingFunction: (int (*)(id, id, void*))comparator
|
||||
context: (void*)context;
|
||||
- (NSString*) componentsJoinedByString: (NSString*)separator;
|
||||
|
||||
- firstObjectCommonWithArray: (NSArray*) otherArray;
|
||||
context: (void*)context;
|
||||
- (NSArray*) sortedArrayUsingFunction: (int (*)(id, id, void*))comparator
|
||||
context: (void*)context
|
||||
hint: (NSData*)hint;
|
||||
- (NSArray*) sortedArrayUsingSelector: (SEL)comparator;
|
||||
- (NSArray*) subarrayWithRange: (NSRange)range;
|
||||
|
||||
- (NSString*) componentsJoinedByString: (NSString*)separator;
|
||||
- (NSArray*) pathsMatchingExtensions: (NSArray*)extensions;
|
||||
|
||||
- (NSEnumerator*) objectEnumerator;
|
||||
- (NSEnumerator*) reverseObjectEnumerator;
|
||||
|
||||
- (NSString*) description;
|
||||
- (NSString*) descriptionWithIndent: (unsigned)level;
|
||||
- (NSString*) descriptionWithLocale: (NSDictionary*)locale;
|
||||
- (NSString*) descriptionWithLocale: (NSDictionary*)locale
|
||||
indent: (unsigned int)level;
|
||||
|
||||
@end
|
||||
|
||||
|
@ -82,19 +103,29 @@
|
|||
@interface NSMutableArray (NonCore)
|
||||
|
||||
+ arrayWithCapacity: (unsigned)numItems;
|
||||
+ initWithCapacity: (unsigned)numItems;
|
||||
|
||||
- (void) removeLastObject;
|
||||
|
||||
- (void) removeObjectIdenticalTo: anObject;
|
||||
- (void) removeObject: anObject;
|
||||
- (void) removeAllObjects;
|
||||
- (void) addObjectsFromArray: (NSArray*)otherArray;
|
||||
- (void) removeObjectsFromIndices: (unsigned*)indices
|
||||
numIndices: (unsigned)count;
|
||||
- (void) replaceObjectsInRange: (NSRange)aRange
|
||||
withObjectsFromArray: (NSArray*)anArray;
|
||||
- (void) replaceObjectsInRange: (NSRange)aRange
|
||||
withObjectsFromArray: (NSArray*)anArray
|
||||
range: (NSRange)anotherRange;
|
||||
- (void) setArray: (NSArray *)otherArray;
|
||||
|
||||
- (void) removeAllObjects;
|
||||
- (void) removeLastObject;
|
||||
- (void) removeObject: anObject;
|
||||
- (void) removeObject: anObject inRange: (NSRange)aRange;
|
||||
- (void) removeObjectIdenticalTo: anObject;
|
||||
- (void) removeObjectIdenticalTo: anObject inRange: (NSRange)aRange;
|
||||
- (void) removeObjectsInArray: (NSArray*)otherArray;
|
||||
- (void) setArray:(NSArray *)otherArray;
|
||||
- (void) removeObjectsInRange: (NSRange)aRange;
|
||||
- (void) removeObjectsFromIndices: (unsigned*)indices
|
||||
numIndices: (unsigned)count;
|
||||
|
||||
- (void) sortUsingFunction: (int(*)(id,id,void*))compare
|
||||
context: (void*)context;
|
||||
context: (void*)context;
|
||||
- (void) sortUsingSelector: (SEL) aSelector;
|
||||
|
||||
@end
|
||||
|
|
|
@ -39,6 +39,7 @@
|
|||
length: (unsigned int)length;
|
||||
+ (id)dataWithContentsOfFile: (NSString*)path;
|
||||
+ (id)dataWithContentsOfMappedFile: (NSString*)path;
|
||||
+ (id)dataWithData: (NSData*)data;
|
||||
- (id)initWithBytes: (const void*)bytes
|
||||
length: (unsigned int)length;
|
||||
- (id)initWithBytesNoCopy: (void*)bytes
|
||||
|
@ -120,6 +121,7 @@
|
|||
- (void) replaceBytesInRange: (NSRange)aRange
|
||||
withBytes: (const void*)bytes;
|
||||
- (void) resetBytesInRange: (NSRange)aRange;
|
||||
- (void) setData: (NSData*)data;
|
||||
|
||||
// Serializing Data
|
||||
|
||||
|
|
|
@ -43,20 +43,30 @@
|
|||
+ allocWithZone: (NSZone*)zone;
|
||||
+ dictionary;
|
||||
+ dictionaryWithContentsOfFile:(NSString *)path;
|
||||
+ dictionaryWithDictionary: (NSDictionary)aDict;
|
||||
+ dictionaryWithObjects: (NSArray*)objects forKeys: (NSArray*)keys;
|
||||
+ dictionaryWithObjects: (id*)objects forKeys: (id*)keys
|
||||
count: (unsigned)count;
|
||||
+ dictionaryWithObjects: (NSArray*)objects forKeys: (NSArray*)keys;
|
||||
+ dictionaryWithObjectsAndKeys: (id)object, ...;
|
||||
- initWithObjects: (NSArray*)objects forKeys: (NSArray*)keys;
|
||||
- initWithDictionary: (NSDictionary*)otherDictionary;
|
||||
- initWithContentsOfFile: (NSString*)path;
|
||||
- initWithDictionary: (NSDictionary*)otherDictionary;
|
||||
- initWithObjects: (NSArray*)objects forKeys: (NSArray*)keys;
|
||||
- initWithObjectsAndKeys: (id)object, ...;
|
||||
|
||||
- (BOOL) isEqualToDictionary: (NSDictionary*)other;
|
||||
- (NSString*) description;
|
||||
- (NSString*) descriptionWithIndent: (unsigned)level;
|
||||
|
||||
- (NSArray*) allKeys;
|
||||
- (NSArray*) allValues;
|
||||
- (NSArray*) allKeysForObject: anObject;
|
||||
- (NSArray*) allValues;
|
||||
- (NSArray*) keysSortedByValueUsingSelector: (SEL)comp;
|
||||
- (NSArray*) objectsForKeys: (NSArray*)keys notFoundMarker: (id)abObject;
|
||||
|
||||
- (NSString*) description;
|
||||
- (NSString*) descriptionInStringsFileFormat;
|
||||
- (NSString*) descriptionWithLocale: (NSDictionary*)locale;
|
||||
- (NSString*) descriptionWithLocale: (NSDictionary*)locale
|
||||
indent: (unsigned int)level;
|
||||
|
||||
- (BOOL) writeToFile: (NSString*)path atomically: (BOOL)useAuxiliaryFile;
|
||||
|
||||
@end
|
||||
|
@ -75,6 +85,7 @@
|
|||
- (void) removeAllObjects;
|
||||
- (void) removeObjectsForKeys: (NSArray*)keyArray;
|
||||
- (void) addEntriesFromDictionary: (NSDictionary*)otherDictionary;
|
||||
- (void) setDictionary: (NSDictionary*)otherDictionary;
|
||||
|
||||
@end
|
||||
|
||||
|
|
|
@ -121,6 +121,9 @@ extern NSString* NSFileHandleOperationException;
|
|||
protocol:(NSString*)protocol
|
||||
forModes:(NSArray*)modes;
|
||||
- (BOOL)readInProgress;
|
||||
- (NSString*)socketAddress;
|
||||
- (NSString*)socketService;
|
||||
- (NSString*)socketProtocol;
|
||||
- (void)writeInBackgroundAndNotify:(NSData*)item forModes:(NSArray*)modes;
|
||||
- (void)writeInBackgroundAndNotify:(NSData*)item;
|
||||
- (BOOL)writeInProgress;
|
||||
|
|
|
@ -280,7 +280,7 @@ enum {
|
|||
|
||||
#ifndef NO_GNUSTEP
|
||||
- (const char *) cStringNoCopy;
|
||||
- (const char *) quotedCString;
|
||||
- (NSString*) descriptionForPropertyList;
|
||||
#endif /* NO_GNUSTEP */
|
||||
|
||||
@end
|
||||
|
|
92
Headers/gnustep/base/NSTask.h
Normal file
92
Headers/gnustep/base/NSTask.h
Normal file
|
@ -0,0 +1,92 @@
|
|||
/* Interface for NSTask for GNUstep
|
||||
Copyright (C) 1998 Free Software Foundation, Inc.
|
||||
|
||||
Written by: Richard Frith-Macdonald <richard@brainstorm.co.uk>
|
||||
Date: 1998
|
||||
|
||||
This file is part of the GNUstep Base Library.
|
||||
|
||||
This library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Library General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2 of the License, or (at your option) any later version.
|
||||
|
||||
This library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Library General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Library General Public
|
||||
License along with this library; if not, write to the Free
|
||||
Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
|
||||
#ifndef __NSTask_h_GNUSTEP_BASE_INCLUDE
|
||||
#define __NSTask_h_GNUSTEP_BASE_INCLUDE
|
||||
|
||||
#include <gnustep/base/preface.h>
|
||||
#include <Foundation/NSObject.h>
|
||||
#include <Foundation/NSString.h>
|
||||
#include <Foundation/NSArray.h>
|
||||
#include <Foundation/NSDictionary.h>
|
||||
#include <Foundation/NSFileHandle.h>
|
||||
|
||||
@interface NSTask : NSObject
|
||||
{
|
||||
NSString *currentDirectoryPath;
|
||||
NSString *launchPath;
|
||||
NSArray *arguments;
|
||||
NSDictionary *environment;
|
||||
NSFileHandle *standardError;
|
||||
NSFileHandle *standardInput;
|
||||
NSFileHandle *standardOutput;
|
||||
int taskId;
|
||||
int terminationStatus;
|
||||
BOOL hasLaunched;
|
||||
BOOL hasTerminated;
|
||||
BOOL hasCollected;
|
||||
BOOL hasNotified;
|
||||
}
|
||||
|
||||
+ (NSTask*)launchedTaskWithLaunchPath:(NSString*)path arguments: (NSArray*)args;
|
||||
|
||||
/*
|
||||
* Querying task parameters.
|
||||
*/
|
||||
- (NSArray*) arguments;
|
||||
- (NSString*) currentDirectoryPath;
|
||||
- (NSDictionary*) environment;
|
||||
- (NSString*) launchPath;
|
||||
- (NSFileHandle*) standardError;
|
||||
- (NSFileHandle*) standardInput;
|
||||
- (NSFileHandle*) standardOutput;
|
||||
|
||||
/*
|
||||
* Setting task parameters.
|
||||
*/
|
||||
- (void)setArguments: (NSArray*)args;
|
||||
- (void)setCurrentDirectoryPath: (NSString*)path;
|
||||
- (void)setEnvironment: (NSDictionary*)env;
|
||||
- (void)setLaunchPath: (NSString*)path;
|
||||
- (void)setStandardError: (NSFileHandle*)hdl;
|
||||
- (void)setStandardInput: (NSFileHandle*)hdl;
|
||||
- (void)setStandardOutput: (NSFileHandle*)hdl;
|
||||
|
||||
/*
|
||||
* Obtaining task state
|
||||
*/
|
||||
- (BOOL) isRunning;
|
||||
- (int) terminationStatus;
|
||||
|
||||
/*
|
||||
* Handling a task.
|
||||
*/
|
||||
- (void) interrupt;
|
||||
- (void) launch;
|
||||
- (void) terminate;
|
||||
- (void) waitUntilExit;
|
||||
@end
|
||||
|
||||
extern NSString* NSTaskDidTerminateNotification;
|
||||
|
||||
#endif /* __NSTask_h_GNUSTEP_BASE_INCLUDE */
|
|
@ -41,10 +41,13 @@
|
|||
BOOL connectOK;
|
||||
BOOL readOK;
|
||||
BOOL writeOK;
|
||||
NSMutableDictionary* readInfo;
|
||||
NSMutableDictionary *readInfo;
|
||||
int readPos;
|
||||
NSMutableArray* writeInfo;
|
||||
NSMutableArray *writeInfo;
|
||||
int writePos;
|
||||
NSString *address;
|
||||
NSString *service;
|
||||
NSString *protocol;
|
||||
}
|
||||
|
||||
- (id)initAsClientAtAddress:address
|
||||
|
|
|
@ -206,65 +206,4 @@
|
|||
OBJC_FREE (*enumState);
|
||||
}
|
||||
|
||||
- (NSString*) descriptionWithIndent: (unsigned)level
|
||||
{
|
||||
int dict_count;
|
||||
id desc;
|
||||
id keyenum = [self keyEnumerator];
|
||||
id key;
|
||||
NSCharacterSet *quotables;
|
||||
|
||||
quotables = [[NSCharacterSet alphanumericCharacterSet] invertedSet];
|
||||
|
||||
dict_count = [self count];
|
||||
desc = [NSMutableString stringWithCapacity: 2];
|
||||
[desc appendString: @"{"];
|
||||
if (dict_count > 0)
|
||||
[desc appendString: @"\n"];
|
||||
|
||||
level += 2;
|
||||
|
||||
while ((key = [keyenum nextObject]))
|
||||
{
|
||||
NSString *string;
|
||||
id object;
|
||||
string = [key description];
|
||||
|
||||
if ([string length] == 0
|
||||
|| [string rangeOfCharacterFromSet: quotables].length > 0)
|
||||
[desc appendFormat: @"%*s%s = ", level, "", [string quotedCString]];
|
||||
else
|
||||
[desc appendFormat: @"%*s%s = ", level, "", [string cStringNoCopy]];
|
||||
object = [self objectAtKey: key];
|
||||
if ([object respondsToSelector: @selector(descriptionWithIndent:)])
|
||||
{
|
||||
/* This a dictionary or array, so don't quote it */
|
||||
string = [object descriptionWithIndent: level];
|
||||
[desc appendFormat: @"%@;\n", string];
|
||||
}
|
||||
else
|
||||
{
|
||||
/* This should be a string or number, so decide if we need to
|
||||
quote it */
|
||||
string = [object description];
|
||||
if ([string length] == 0
|
||||
|| [string rangeOfCharacterFromSet: quotables].length > 0)
|
||||
[desc appendFormat: @"%s;\n", [string quotedCString]];
|
||||
else
|
||||
[desc appendFormat: @"%s;\n", [string cStringNoCopy]];
|
||||
}
|
||||
}
|
||||
if (dict_count == 0)
|
||||
level = 0;
|
||||
else
|
||||
level -= 2;
|
||||
[desc appendFormat: @"%*s}", level, ""];
|
||||
return desc;
|
||||
}
|
||||
|
||||
- (NSString*) description
|
||||
{
|
||||
return [self descriptionWithIndent: 0];
|
||||
}
|
||||
|
||||
@end
|
||||
|
|
|
@ -352,6 +352,7 @@ NSScanner.m \
|
|||
NSSerializer.m \
|
||||
NSSet.m \
|
||||
NSString.m \
|
||||
NSTask.m \
|
||||
NSThread.m \
|
||||
NSTimer.m \
|
||||
NSTimeZone.m \
|
||||
|
@ -440,6 +441,7 @@ Foundation/NSScanner.h \
|
|||
Foundation/NSSerialization.h \
|
||||
Foundation/NSSet.h \
|
||||
Foundation/NSString.h \
|
||||
Foundation/NSTask.h \
|
||||
Foundation/NSThread.h \
|
||||
Foundation/NSTimer.h \
|
||||
Foundation/NSUserDefaults.h \
|
||||
|
|
|
@ -94,4 +94,9 @@
|
|||
_contents_array[i] = newObject;
|
||||
}
|
||||
|
||||
- (id) minObject
|
||||
{
|
||||
return [self firstObject];
|
||||
}
|
||||
|
||||
@end
|
||||
|
|
361
Source/NSArray.m
361
Source/NSArray.m
|
@ -30,7 +30,7 @@
|
|||
#include <limits.h>
|
||||
#include <Foundation/NSUtilities.h>
|
||||
#include <Foundation/NSException.h>
|
||||
#include <Foundation/NSCharacterSet.h>
|
||||
#include <Foundation/NSAutoreleasePool.h>
|
||||
|
||||
@class NSArrayEnumerator;
|
||||
@class NSArrayEnumeratorReverse;
|
||||
|
@ -111,6 +111,16 @@ static Class NSMutableArray_concrete_class;
|
|||
autorelease];
|
||||
}
|
||||
|
||||
+ arrayWithArray: (NSArray*)array
|
||||
{
|
||||
return [[[self alloc] initWithArray: array] autorelease];
|
||||
}
|
||||
|
||||
+ arrayWithContentsOfFile: (NSString*)file
|
||||
{
|
||||
return [[[self alloc] initWithContentsOfFile: file] autorelease];
|
||||
}
|
||||
|
||||
+ arrayWithObject: anObject
|
||||
{
|
||||
if (anObject == nil)
|
||||
|
@ -218,6 +228,12 @@ static Class NSMutableArray_concrete_class;
|
|||
return [self autorelease];
|
||||
}
|
||||
|
||||
+ arrayWithObjects: (id*)objects count: (unsigned)count
|
||||
{
|
||||
return [[[self alloc] initWithObjects: objects count: count]
|
||||
autorelease];
|
||||
}
|
||||
|
||||
- initWithArray: (NSArray*)array
|
||||
{
|
||||
int i, c;
|
||||
|
@ -232,6 +248,21 @@ static Class NSMutableArray_concrete_class;
|
|||
return self;
|
||||
}
|
||||
|
||||
- (void) getObjects: (id*)aBuffer
|
||||
{
|
||||
int i, c = [self count];
|
||||
for (i = 0; i < c; i++)
|
||||
aBuffer[i] = [self objectAtIndex: i];
|
||||
}
|
||||
|
||||
- (void) getObjects: (id*)aBuffer range: (NSRange)aRange
|
||||
{
|
||||
int i, j = 0, c = [self count], e = aRange.location + aRange.length;
|
||||
if (c < e)
|
||||
e = c;
|
||||
for (i = aRange.location; i < c; i++)
|
||||
aBuffer[j++] = [self objectAtIndex: i];
|
||||
}
|
||||
|
||||
- (unsigned) indexOfObjectIdenticalTo:anObject
|
||||
{
|
||||
|
@ -242,6 +273,17 @@ static Class NSMutableArray_concrete_class;
|
|||
return NSNotFound;
|
||||
}
|
||||
|
||||
- (unsigned) indexOfObjectIdenticalTo:anObject inRange: (NSRange)aRange
|
||||
{
|
||||
int i, e = aRange.location + aRange.length, c = [self count];
|
||||
if (c < e)
|
||||
e = c;
|
||||
for (i = aRange.location; i < e; i++)
|
||||
if (anObject == [self objectAtIndex:i])
|
||||
return i;
|
||||
return NSNotFound;
|
||||
}
|
||||
|
||||
/* Inefficient, should be overridden. */
|
||||
- (unsigned) indexOfObject: anObject
|
||||
{
|
||||
|
@ -252,6 +294,21 @@ static Class NSMutableArray_concrete_class;
|
|||
return NSNotFound;
|
||||
}
|
||||
|
||||
/* Inefficient, should be overridden. */
|
||||
- (unsigned) indexOfObject: anObject inRange: (NSRange)aRange
|
||||
{
|
||||
int i, e = aRange.location + aRange.length, c = [self count];
|
||||
if (c < e)
|
||||
e = c;
|
||||
for (i = aRange.location; i < e; i++)
|
||||
{
|
||||
id o = [self objectAtIndex: i];
|
||||
if (anObject == o || [o isEqual: anObject])
|
||||
return i;
|
||||
}
|
||||
return NSNotFound;
|
||||
}
|
||||
|
||||
- (BOOL) containsObject: anObject
|
||||
{
|
||||
return ([self indexOfObject:anObject] != NSNotFound);
|
||||
|
@ -287,17 +344,27 @@ static Class NSMutableArray_concrete_class;
|
|||
- (void) makeObjectsPerform: (SEL)aSelector
|
||||
{
|
||||
int i, c = [self count];
|
||||
for (i = 0; i < c; i++)
|
||||
for (i = c-1; i >= 0; i--)
|
||||
[[self objectAtIndex:i] perform:aSelector];
|
||||
}
|
||||
|
||||
- (void) makeObjectsPerformSelector: (SEL)aSelector
|
||||
{
|
||||
[self makeObjectsPerform: aSelector];
|
||||
}
|
||||
|
||||
- (void) makeObjectsPerform: (SEL)aSelector withObject:argument
|
||||
{
|
||||
int i, c = [self count];
|
||||
for (i = 0; i < c; i++)
|
||||
for (i = c-1; i >= 0; i--)
|
||||
[[self objectAtIndex:i] perform:aSelector withObject:argument];
|
||||
}
|
||||
|
||||
- (void) makeObjectsPerformSelector: (SEL)aSelector withObject:argument
|
||||
{
|
||||
[self makeObjectsPerform: aSelector withObject:argument];
|
||||
}
|
||||
|
||||
|
||||
- (NSArray*) sortedArrayUsingSelector: (SEL)comparator
|
||||
{
|
||||
|
@ -312,10 +379,26 @@ static Class NSMutableArray_concrete_class;
|
|||
- (NSArray*) sortedArrayUsingFunction: (int(*)(id,id,void*))comparator
|
||||
context: (void*)context
|
||||
{
|
||||
id sortedArray = [[self mutableCopy] autorelease];
|
||||
return [self sortedArrayUsingFunction: comparator context: context hint: nil];
|
||||
}
|
||||
|
||||
- (NSData*) sortedArrayHint
|
||||
{
|
||||
return nil;
|
||||
}
|
||||
|
||||
- (NSArray*) sortedArrayUsingFunction: (int(*)(id,id,void*))comparator
|
||||
context: (void*)context
|
||||
hint: (NSData*)hint
|
||||
{
|
||||
NSMutableArray *sortedArray;
|
||||
NSArray *result;
|
||||
|
||||
sortedArray = [[NSMutableArray alloc] initWithArray: self];
|
||||
[sortedArray sortUsingFunction:comparator context:context];
|
||||
return [[sortedArray copy] autorelease];
|
||||
result = [NSArray arrayWithArray: sortedArray];
|
||||
[sortedArray release];
|
||||
return result;
|
||||
}
|
||||
|
||||
- (NSString*) componentsJoinedByString: (NSString*)separator
|
||||
|
@ -334,6 +417,19 @@ static Class NSMutableArray_concrete_class;
|
|||
return s;
|
||||
}
|
||||
|
||||
- (NSArray*) pathsMatchingExtensions: (NSArray*)extensions
|
||||
{
|
||||
int i, c = [self count];
|
||||
NSMutableArray *a = [NSMutableArray arrayWithCapacity: 1];
|
||||
for (i = 0; i < c; i++)
|
||||
{
|
||||
id o = [self objectAtIndex: i];
|
||||
if ([o isKindOfClass: [NSString class]])
|
||||
if ([extensions containsObject: [o pathExtension]])
|
||||
[a addObject: o];
|
||||
}
|
||||
return a;
|
||||
}
|
||||
|
||||
- firstObjectCommonWithArray: (NSArray*)otherArray
|
||||
{
|
||||
|
@ -391,69 +487,126 @@ static Class NSMutableArray_concrete_class;
|
|||
|
||||
- (NSString*) description
|
||||
{
|
||||
return [self descriptionWithIndent: 0];
|
||||
return [self descriptionWithLocale: nil];
|
||||
}
|
||||
|
||||
- (NSString*) descriptionWithIndent: (unsigned)level
|
||||
- (NSString*) descriptionWithLocale: (NSDictionary*)locale
|
||||
{
|
||||
id string;
|
||||
id desc;
|
||||
id object;
|
||||
int count = [self count];
|
||||
int i;
|
||||
NSCharacterSet *quotables;
|
||||
return [self descriptionWithLocale: locale indent: 0];
|
||||
}
|
||||
|
||||
- (NSString*) descriptionWithLocale: (NSDictionary*)locale
|
||||
indent: (unsigned int)level
|
||||
{
|
||||
NSMutableString *result;
|
||||
NSMutableArray *plists;
|
||||
int count;
|
||||
int size;
|
||||
NSAutoreleasePool *arp;
|
||||
int indentSize;
|
||||
int indentBase;
|
||||
NSMutableString *iBaseString;
|
||||
NSMutableString *iSizeString;
|
||||
int i;
|
||||
|
||||
quotables = [[NSCharacterSet alphanumericCharacterSet] invertedSet];
|
||||
arp = [[NSAutoreleasePool alloc] init];
|
||||
|
||||
desc = [NSMutableString stringWithCapacity: 2];
|
||||
[desc appendString: @"("];
|
||||
if (count > 0)
|
||||
{
|
||||
object = [self objectAtIndex: 0];
|
||||
if ([object respondsToSelector: @selector(descriptionWithIndent:)])
|
||||
{
|
||||
/* This a dictionary or array, so don't quote it */
|
||||
string = [object descriptionWithIndent: 0];
|
||||
[desc appendString: string];
|
||||
}
|
||||
else
|
||||
{
|
||||
/* This should be a string or number, so decide if we need to
|
||||
quote it */
|
||||
string = [object description];
|
||||
if ([string length] == 0
|
||||
|| [string rangeOfCharacterFromSet: quotables].length > 0)
|
||||
[desc appendFormat: @"%s", [string quotedCString]];
|
||||
else
|
||||
[desc appendString: string];
|
||||
}
|
||||
/*
|
||||
* Indentation is at four space intervals using tab characters to
|
||||
* replace multiples of eight spaces.
|
||||
*
|
||||
* We work out the sizes of the strings needed to perform indentation for
|
||||
* this level and build strings to make up the indentation.
|
||||
*/
|
||||
indentBase = level << 2;
|
||||
count = indentBase >> 3;
|
||||
if ((indentBase % 8) == 0) {
|
||||
indentBase = count;
|
||||
}
|
||||
for (i=1; i<count; i++)
|
||||
{
|
||||
object = [self objectAtIndex: i];
|
||||
|
||||
[desc appendString: @", "];
|
||||
if ([object respondsToSelector: @selector(descriptionWithIndent:)])
|
||||
{
|
||||
/* This a dictionary or array, so don't quote it */
|
||||
string = [object descriptionWithIndent: 0];
|
||||
[desc appendString: string];
|
||||
}
|
||||
else
|
||||
{
|
||||
/* This should be a string or number, so decide if we need to
|
||||
quote it */
|
||||
string = [object description];
|
||||
if ([string length] == 0
|
||||
|| [string rangeOfCharacterFromSet: quotables].length > 0)
|
||||
[desc appendString: [NSString stringWithCString:
|
||||
[string quotedCString]]];
|
||||
else
|
||||
[desc appendString: string];
|
||||
}
|
||||
else {
|
||||
indentBase == count + 4;
|
||||
}
|
||||
[desc appendString: @")"];
|
||||
return desc;
|
||||
iBaseString = [NSMutableString stringWithCapacity: indentBase];
|
||||
for (i = 0; i < count; i++) {
|
||||
[iBaseString appendString: @"\t"];
|
||||
}
|
||||
if (count != indentBase) {
|
||||
[iBaseString appendString: @" "];
|
||||
}
|
||||
|
||||
level++;
|
||||
indentSize = level << 2;
|
||||
count = indentSize >> 3;
|
||||
if ((indentSize % 8) == 0) {
|
||||
indentSize = count;
|
||||
}
|
||||
else {
|
||||
indentSize == count + 4;
|
||||
}
|
||||
iSizeString = [NSMutableString stringWithCapacity: indentSize];
|
||||
for (i = 0; i < count; i++) {
|
||||
[iSizeString appendString: @"\t"];
|
||||
}
|
||||
if (count != indentSize) {
|
||||
[iSizeString appendString: @" "];
|
||||
}
|
||||
|
||||
/*
|
||||
* Basic size is - opening bracket, newline, closing bracket,
|
||||
* indentation for the closing bracket, and a nul terminator.
|
||||
*/
|
||||
size = 4 + indentBase;
|
||||
|
||||
count = [self count];
|
||||
plists = [NSMutableArray arrayWithCapacity: count];
|
||||
|
||||
for (i = 0; i < count; i++) {
|
||||
id item;
|
||||
|
||||
item = [self objectAtIndex: i];
|
||||
if ([item isKindOfClass: [NSString class]]) {
|
||||
item = [item descriptionForPropertyList];
|
||||
}
|
||||
else if ([item respondsToSelector:
|
||||
@selector(descriptionWithLocale:indent:)]) {
|
||||
item = [item descriptionWithLocale: locale indent: level];
|
||||
}
|
||||
else if ([item respondsToSelector:
|
||||
@selector(descriptionWithLocale:)]) {
|
||||
item = [item descriptionWithLocale: locale];
|
||||
}
|
||||
else {
|
||||
item = [item description];
|
||||
}
|
||||
[plists addObject: item];
|
||||
|
||||
size += [item length] + indentSize;
|
||||
if (i == count - 1) {
|
||||
size += 1; /* newline */
|
||||
}
|
||||
else {
|
||||
size += 2; /* ',' and newline */
|
||||
}
|
||||
}
|
||||
|
||||
result = [[NSMutableString alloc] initWithCapacity: size];
|
||||
[result appendString: @"(\n"];
|
||||
for (i = 0; i < count; i++) {
|
||||
[result appendString: iSizeString];
|
||||
[result appendString: [plists objectAtIndex: i]];
|
||||
if (i == count - 1) {
|
||||
[result appendString: @"\n"];
|
||||
}
|
||||
else {
|
||||
[result appendString: @",\n"];
|
||||
}
|
||||
}
|
||||
[result appendString: iBaseString];
|
||||
[result appendString: @")"];
|
||||
|
||||
[arp release];
|
||||
|
||||
return [result autorelease];
|
||||
}
|
||||
|
||||
/* The NSCopying Protocol */
|
||||
|
@ -520,6 +673,27 @@ static Class NSMutableArray_concrete_class;
|
|||
[self subclassResponsibility:_cmd];
|
||||
}
|
||||
|
||||
- (void) replaceObjectsInRange: (NSRange)aRange
|
||||
withObjectsFromArray: (NSArray*)anArray
|
||||
{
|
||||
int i;
|
||||
|
||||
if ([self count] <= aRange.location)
|
||||
[NSException raise: NSRangeException
|
||||
format: @"Replacing objects beyond end of array."];
|
||||
[self removeObjectsInRange: aRange];
|
||||
for (i = [anArray count] - 1; i >= 0; i--)
|
||||
[self insertObject: [anArray objectAtIndex: i] atIndex: aRange.location];
|
||||
}
|
||||
|
||||
- (void) replaceObjectsInRange: (NSRange)aRange
|
||||
withObjectsFromArray: (NSArray*)anArray
|
||||
range: (NSRange)anotherRange
|
||||
{
|
||||
[self replaceObjectsInRange: aRange
|
||||
withObjectsFromArray: [anArray subarrayWithRange: anotherRange]];
|
||||
}
|
||||
|
||||
- (void) insertObject: anObject atIndex: (unsigned)index
|
||||
{
|
||||
[self subclassResponsibility:_cmd];
|
||||
|
@ -541,6 +715,29 @@ static Class NSMutableArray_concrete_class;
|
|||
autorelease];
|
||||
}
|
||||
|
||||
- initWithContentsOfFile: (NSString*)file
|
||||
{
|
||||
NSString *myString;
|
||||
|
||||
myString = [[NSString alloc] initWithContentsOfFile:file];
|
||||
if (myString)
|
||||
{
|
||||
id result = [myString propertyList];
|
||||
if ( [result isKindOfClass: [NSArray class]] )
|
||||
{
|
||||
[self initWithArray: result];
|
||||
return self;
|
||||
}
|
||||
}
|
||||
[self dealloc];
|
||||
return nil;
|
||||
}
|
||||
|
||||
- (BOOL)writeToFile:(NSString *)path atomically:(BOOL)useAuxiliaryFile
|
||||
{
|
||||
return [[self description] writeToFile:path atomically:useAuxiliaryFile];
|
||||
}
|
||||
|
||||
/* Override our superclass's designated initializer to go our's */
|
||||
- initWithObjects: (id*)objects count: (unsigned)count
|
||||
{
|
||||
|
@ -578,6 +775,38 @@ static Class NSMutableArray_concrete_class;
|
|||
[anObject release];
|
||||
}
|
||||
|
||||
- (void) removeObject: anObject inRange:(NSRange)aRange
|
||||
{
|
||||
int c = [self count], s = aRange.location;
|
||||
int i = aRange.location + aRange.length;
|
||||
if (i > c)
|
||||
i = c;
|
||||
[anObject retain];
|
||||
for (i--; i >= s; i--)
|
||||
{
|
||||
id o = [self objectAtIndex: i];
|
||||
if (o == anObject || [o isEqual: anObject])
|
||||
[self removeObjectAtIndex:i];
|
||||
}
|
||||
[anObject release];
|
||||
}
|
||||
|
||||
- (void) removeObjectIdenticalTo: anObject inRange:(NSRange)aRange
|
||||
{
|
||||
int c = [self count], s = aRange.location;
|
||||
int i = aRange.location + aRange.length;
|
||||
if (i > c)
|
||||
i = c;
|
||||
[anObject retain];
|
||||
for (i--; i >= s; i--)
|
||||
{
|
||||
id o = [self objectAtIndex: i];
|
||||
if (o == anObject)
|
||||
[self removeObjectAtIndex:i];
|
||||
}
|
||||
[anObject release];
|
||||
}
|
||||
|
||||
- (void) removeObject: anObject
|
||||
{
|
||||
unsigned index;
|
||||
|
@ -635,6 +864,16 @@ static Class NSMutableArray_concrete_class;
|
|||
[self removeObject:[otherArray objectAtIndex:i]];
|
||||
}
|
||||
|
||||
- (void) removeObjectsInRange: (NSRange)aRange
|
||||
{
|
||||
int i, s = aRange.location, c = [self count];
|
||||
i = aRange.location + aRange.length;
|
||||
if (c < i)
|
||||
i = c;
|
||||
for (i--; i >= s; i--)
|
||||
[self removeObjectAtIndex: i];
|
||||
}
|
||||
|
||||
- (void) sortUsingSelector: (SEL)comparator
|
||||
{
|
||||
int compare(id elem1, id elem2, void* context)
|
||||
|
|
|
@ -257,6 +257,12 @@ readContentsOfFile(NSString* path, void** buf, unsigned* len)
|
|||
#endif
|
||||
}
|
||||
|
||||
+ (id) dataWithData: (NSData*)data
|
||||
{
|
||||
return [[[NSDataMalloc alloc] initWithBytes: [data bytes]
|
||||
length: [data length]] autorelease];
|
||||
}
|
||||
|
||||
- (id) initWithBytes: (const void*)bytes
|
||||
length: (unsigned int)length
|
||||
{
|
||||
|
@ -317,7 +323,7 @@ readContentsOfFile(NSString* path, void** buf, unsigned* len)
|
|||
{
|
||||
dest[j++] = num2char((src[i]>>4) & 0x0f);
|
||||
dest[j] = num2char(src[i] & 0x0f);
|
||||
if((i&0x3) == 3)
|
||||
if((i&0x3) == 3 && i != length-1)
|
||||
/* if we've just finished a 32-bit int, print a space */
|
||||
dest[++j] = ' ';
|
||||
}
|
||||
|
@ -731,12 +737,22 @@ readContentsOfFile(NSString* path, void** buf, unsigned* len)
|
|||
intBuffer[i] = network_int_to_host (intBuffer[i]);
|
||||
}
|
||||
|
||||
- (id) copy
|
||||
{
|
||||
return [self copyWithZone: NSDefaultMallocZone()];
|
||||
}
|
||||
|
||||
- (id) copyWithZone: (NSZone*)zone
|
||||
{
|
||||
[self subclassResponsibility:_cmd];
|
||||
return nil;
|
||||
}
|
||||
|
||||
- (id) mutableCopy
|
||||
{
|
||||
return [self mutableCopyWithZone: NSDefaultMallocZone()];
|
||||
}
|
||||
|
||||
- (id) mutableCopyWithZone: (NSZone*)zone
|
||||
{
|
||||
[self subclassResponsibility:_cmd];
|
||||
|
@ -825,6 +841,13 @@ readContentsOfFile(NSString* path, void** buf, unsigned* len)
|
|||
autorelease];
|
||||
}
|
||||
|
||||
+ (id) dataWithData: (NSData*)data
|
||||
{
|
||||
return [[[NSMutableDataMalloc alloc] initWithBytes: [data bytes]
|
||||
length: [data length]]
|
||||
autorelease];
|
||||
}
|
||||
|
||||
+ (id) dataWithLength: (unsigned int)length
|
||||
{
|
||||
return [[[NSMutableDataMalloc alloc] initWithLength:length]
|
||||
|
@ -933,6 +956,14 @@ readContentsOfFile(NSString* path, void** buf, unsigned* len)
|
|||
memset((char*)[self bytes] + aRange.location, 0, aRange.length);
|
||||
}
|
||||
|
||||
- (void) setData: (NSData*)data
|
||||
{
|
||||
NSRange r = NSMakeRange(0, [data length]);
|
||||
|
||||
[self setCapacity: [data length]];
|
||||
[self replaceBytesInRange: r withBytes: [data bytes]];
|
||||
}
|
||||
|
||||
// Serializing Data
|
||||
|
||||
- (void)serializeAlignedBytesLength:(unsigned int)length
|
||||
|
|
|
@ -28,8 +28,9 @@
|
|||
#include <Foundation/NSGDictionary.h>
|
||||
#include <Foundation/NSArray.h>
|
||||
#include <Foundation/NSUtilities.h>
|
||||
#include <gnustep/base/NSString.h>
|
||||
#include <gnustep/base/NSException.h>
|
||||
#include <Foundation/NSString.h>
|
||||
#include <Foundation/NSException.h>
|
||||
#include <Foundation/NSAutoreleasePool.h>
|
||||
#include <assert.h>
|
||||
|
||||
@interface NSDictionaryNonCore : NSDictionary
|
||||
|
@ -315,6 +316,44 @@ static Class NSMutableDictionary_concrete_class;
|
|||
autorelease];
|
||||
}
|
||||
|
||||
struct foo { NSDictionary *d; SEL s; };
|
||||
|
||||
static int
|
||||
compareIt(id o1, id o2, void* context)
|
||||
{
|
||||
struct foo *f = (struct foo*)context;
|
||||
o1 = [f->d objectForKey: o1];
|
||||
o2 = [f->d objectForKey: o2];
|
||||
return (int)[o1 performSelector: f->s withObject: o2];
|
||||
}
|
||||
|
||||
- (NSArray*)keysSortedByValueUsingSelector: (SEL)comp
|
||||
{
|
||||
struct foo info;
|
||||
id k;
|
||||
|
||||
info.d = self;
|
||||
info.s = comp;
|
||||
k = [[self allKeys] sortedArrayUsingFunction: compareIt context: &info];
|
||||
}
|
||||
|
||||
- (NSArray*) objectsForKeys: (NSArray*)keys notFoundMarker: (id)marker
|
||||
{
|
||||
int i, c = [keys count];
|
||||
id obuf[c];
|
||||
|
||||
for (i = 0; i < c; i++)
|
||||
{
|
||||
id o = [self objectForKey: [keys objectAtIndex: i]];
|
||||
|
||||
if (o)
|
||||
obuf[i] = o;
|
||||
else
|
||||
obuf[i] = marker;
|
||||
}
|
||||
return [NSArray arrayWithObjects: obuf count: c];
|
||||
}
|
||||
|
||||
- (BOOL)writeToFile:(NSString *)path atomically:(BOOL)useAuxiliaryFile
|
||||
{
|
||||
return [[self description] writeToFile:path atomically:useAuxiliaryFile];
|
||||
|
@ -348,6 +387,239 @@ static Class NSMutableDictionary_concrete_class;
|
|||
initWithDictionary:self];
|
||||
}
|
||||
|
||||
- (NSString*) description
|
||||
{
|
||||
return [self descriptionWithLocale: nil];
|
||||
}
|
||||
|
||||
- (NSString*) descriptionInStringsFileFormat
|
||||
{
|
||||
NSMutableString *result;
|
||||
NSMutableArray *plists;
|
||||
NSMutableArray *theKeys;
|
||||
int numKeys;
|
||||
int size;
|
||||
NSAutoreleasePool *arp;
|
||||
int i;
|
||||
|
||||
arp = [[NSAutoreleasePool alloc] init];
|
||||
|
||||
size = 1;
|
||||
|
||||
theKeys = [NSMutableArray arrayWithArray: [self allKeys]];
|
||||
numKeys = [theKeys count];
|
||||
plists = [NSMutableArray arrayWithCapacity: numKeys];
|
||||
|
||||
for (i = 0; i < numKeys; i++) {
|
||||
NSString *newKey;
|
||||
id key;
|
||||
id item;
|
||||
|
||||
key = [theKeys objectAtIndex:i];
|
||||
item = [self objectForKey: key];
|
||||
if ([key respondsToSelector: @selector(descriptionForPropertyList)]) {
|
||||
newKey = [key descriptionForPropertyList];
|
||||
}
|
||||
else {
|
||||
newKey = [key description];
|
||||
}
|
||||
if (newKey != key) {
|
||||
key = newKey;
|
||||
[theKeys replaceObjectAtIndex: i withObject: key];
|
||||
}
|
||||
|
||||
if (item == nil) {
|
||||
item = @"";
|
||||
}
|
||||
else if ([item isKindOfClass: [NSString class]]) {
|
||||
item = [item descriptionForPropertyList];
|
||||
}
|
||||
else {
|
||||
item = [item description];
|
||||
}
|
||||
[plists addObject: item];
|
||||
|
||||
size += [key length] + [item length];
|
||||
if ([item length]) {
|
||||
size += 5;
|
||||
}
|
||||
else {
|
||||
size += 2;
|
||||
}
|
||||
}
|
||||
|
||||
result = [[NSMutableString alloc] initWithCapacity: size];
|
||||
for (i = 0; i < numKeys; i++) {
|
||||
NSString* item = [plists objectAtIndex: i];
|
||||
|
||||
[result appendString: [theKeys objectAtIndex: i]];
|
||||
if ([item length]) {
|
||||
[result appendString: @" = "];
|
||||
[result appendString: item];
|
||||
}
|
||||
[result appendString: @";\n"];
|
||||
}
|
||||
|
||||
[arp release];
|
||||
|
||||
return [result autorelease];
|
||||
}
|
||||
|
||||
- (NSString*) descriptionWithLocale: (NSDictionary*)locale
|
||||
{
|
||||
return [self descriptionWithLocale: locale indent: 0];
|
||||
}
|
||||
|
||||
- (NSString*) descriptionWithLocale: (NSDictionary*)locale
|
||||
indent: (unsigned int)level
|
||||
{
|
||||
NSMutableString *result;
|
||||
NSEnumerator *enumerator;
|
||||
NSMutableArray *plists;
|
||||
NSMutableArray *theKeys;
|
||||
id key;
|
||||
BOOL canCompare = YES;
|
||||
int numKeys;
|
||||
int count;
|
||||
int size;
|
||||
NSAutoreleasePool *arp;
|
||||
int indentSize;
|
||||
int indentBase;
|
||||
NSMutableString *iBaseString;
|
||||
NSMutableString *iSizeString;
|
||||
int i;
|
||||
|
||||
arp = [[NSAutoreleasePool alloc] init];
|
||||
|
||||
/*
|
||||
* Indentation is at four space intervals using tab characters to
|
||||
* replace multiples of eight spaces.
|
||||
*
|
||||
* We work out the sizes of the strings needed to perform indentation for
|
||||
* this level and build strings to make up the indentation.
|
||||
*/
|
||||
indentBase = level << 2;
|
||||
count = indentBase >> 3;
|
||||
if ((indentBase % 8) == 0) {
|
||||
indentBase = count;
|
||||
}
|
||||
else {
|
||||
indentBase == count + 4;
|
||||
}
|
||||
iBaseString = [NSMutableString stringWithCapacity: indentBase];
|
||||
for (i = 0; i < count; i++) {
|
||||
[iBaseString appendString: @"\t"];
|
||||
}
|
||||
if (count != indentBase) {
|
||||
[iBaseString appendString: @" "];
|
||||
}
|
||||
|
||||
level++;
|
||||
indentSize = level << 2;
|
||||
count = indentSize >> 3;
|
||||
if ((indentSize % 8) == 0) {
|
||||
indentSize = count;
|
||||
}
|
||||
else {
|
||||
indentSize == count + 4;
|
||||
}
|
||||
iSizeString = [NSMutableString stringWithCapacity: indentSize];
|
||||
for (i = 0; i < count; i++) {
|
||||
[iSizeString appendString: @"\t"];
|
||||
}
|
||||
if (count != indentSize) {
|
||||
[iSizeString appendString: @" "];
|
||||
}
|
||||
|
||||
/*
|
||||
* Basic size is - opening bracket, newline, closing bracket,
|
||||
* indentation for the closing bracket, and a nul terminator.
|
||||
*/
|
||||
size = 4 + indentBase;
|
||||
|
||||
enumerator = [self keyEnumerator];
|
||||
while ((key = [enumerator nextObject]) != nil) {
|
||||
if ([key respondsToSelector: @selector(compare:)] == NO) {
|
||||
canCompare = NO;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (canCompare) {
|
||||
theKeys = [NSMutableArray arrayWithArray:
|
||||
[[self allKeys] sortedArrayUsingSelector: @selector(compare:)]];
|
||||
}
|
||||
else {
|
||||
theKeys = [NSMutableArray arrayWithArray: [self allKeys]];
|
||||
}
|
||||
|
||||
numKeys = [theKeys count];
|
||||
plists = [NSMutableArray arrayWithCapacity: numKeys];
|
||||
|
||||
for (i = 0; i < numKeys; i++) {
|
||||
NSString *newKey;
|
||||
id item;
|
||||
|
||||
key = [theKeys objectAtIndex:i];
|
||||
item = [self objectForKey: key];
|
||||
if ([key respondsToSelector: @selector(descriptionForPropertyList)]) {
|
||||
newKey = [key descriptionForPropertyList];
|
||||
}
|
||||
else {
|
||||
newKey = [key description];
|
||||
}
|
||||
if (newKey != key) {
|
||||
key = newKey;
|
||||
[theKeys replaceObjectAtIndex: i withObject: key];
|
||||
}
|
||||
|
||||
if ([item isKindOfClass: [NSString class]]) {
|
||||
item = [item descriptionForPropertyList];
|
||||
}
|
||||
else if ([item respondsToSelector:
|
||||
@selector(descriptionWithLocale:indent:)]) {
|
||||
item = [item descriptionWithLocale: locale indent: level];
|
||||
}
|
||||
else if ([item respondsToSelector:
|
||||
@selector(descriptionWithLocale:)]) {
|
||||
item = [item descriptionWithLocale: locale];
|
||||
}
|
||||
else {
|
||||
item = [item description];
|
||||
}
|
||||
[plists addObject: item];
|
||||
|
||||
size += [key length] + [item length] + indentSize;
|
||||
if (i == numKeys - 1) {
|
||||
size += 4; /* ' = ' and newline */
|
||||
}
|
||||
else {
|
||||
size += 5; /* ' = ' and ';' and newline */
|
||||
}
|
||||
}
|
||||
|
||||
result = [[NSMutableString alloc] initWithCapacity: size];
|
||||
[result appendString: @"{\n"];
|
||||
for (i = 0; i < numKeys; i++) {
|
||||
[result appendString: iSizeString];
|
||||
[result appendString: [theKeys objectAtIndex: i]];
|
||||
[result appendString: @" = "];
|
||||
[result appendString: [plists objectAtIndex: i]];
|
||||
if (i == numKeys - 1) {
|
||||
[result appendString: @"\n"];
|
||||
}
|
||||
else {
|
||||
[result appendString: @";\n"];
|
||||
}
|
||||
}
|
||||
[result appendString: iBaseString];
|
||||
[result appendString: @"}"];
|
||||
|
||||
[arp release];
|
||||
|
||||
return [result autorelease];
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
@implementation NSMutableDictionary
|
||||
|
@ -425,5 +697,10 @@ static Class NSMutableDictionary_concrete_class;
|
|||
[self setObject:[other objectForKey:k] forKey:k];
|
||||
}
|
||||
|
||||
- (void) setDictionary: (NSDictionary*)otherDictionary
|
||||
{
|
||||
[self removeAllObjects];
|
||||
[self addEntriesFromDictionary: otherDictionary];
|
||||
}
|
||||
|
||||
@end
|
||||
|
|
|
@ -304,6 +304,21 @@ NSString* NSFileHandleOperationException =
|
|||
return NO;
|
||||
}
|
||||
|
||||
- (NSString*)socketAddress
|
||||
{
|
||||
return nil;
|
||||
}
|
||||
|
||||
- (NSString*)socketService
|
||||
{
|
||||
return nil;
|
||||
}
|
||||
|
||||
- (NSString*)socketProtocol
|
||||
{
|
||||
return nil;
|
||||
}
|
||||
|
||||
- (void)writeInBackgroundAndNotify:(NSData*)item forModes:(NSArray*)modes
|
||||
{
|
||||
[self subclassResponsibility:_cmd];
|
||||
|
|
|
@ -2396,70 +2396,84 @@ else
|
|||
return NULL;
|
||||
}
|
||||
|
||||
- (const char *) quotedCString
|
||||
- (NSString*) descriptionForPropertyList
|
||||
{
|
||||
const char *from;
|
||||
char *buf;
|
||||
char *ptr;
|
||||
int len = 0;
|
||||
static NSCharacterSet *quotables = nil;
|
||||
|
||||
for (from = [self cStringNoCopy]; *from; from++) {
|
||||
switch (*from) {
|
||||
case '\a':
|
||||
case '\b':
|
||||
case '\t':
|
||||
case '\r':
|
||||
case '\n':
|
||||
case '\v':
|
||||
case '\f':
|
||||
case '\\':
|
||||
case '\'' :
|
||||
case '"' :
|
||||
len += 2;
|
||||
break;
|
||||
|
||||
default:
|
||||
if (isprint(*from) || *from == ' ') {
|
||||
len++;
|
||||
}
|
||||
else {
|
||||
len += 4;
|
||||
}
|
||||
break;
|
||||
}
|
||||
if (quotables == nil) {
|
||||
quotables = [[NSCharacterSet alphanumericCharacterSet] invertedSet];
|
||||
[quotables retain];
|
||||
}
|
||||
|
||||
buf = objc_malloc(len + 3);
|
||||
ptr = buf;
|
||||
*ptr++ = '"';
|
||||
for (from = [self cStringNoCopy]; *from; from++) {
|
||||
switch (*from) {
|
||||
case '\a': *ptr++ = '\\'; *ptr++ = 'a'; break;
|
||||
case '\b': *ptr++ = '\\'; *ptr++ = 'b'; break;
|
||||
case '\t': *ptr++ = '\\'; *ptr++ = 't'; break;
|
||||
case '\r': *ptr++ = '\\'; *ptr++ = 'r'; break;
|
||||
case '\n': *ptr++ = '\\'; *ptr++ = 'n'; break;
|
||||
case '\v': *ptr++ = '\\'; *ptr++ = 'v'; break;
|
||||
case '\f': *ptr++ = '\\'; *ptr++ = 'f'; break;
|
||||
case '\\': *ptr++ = '\\'; *ptr++ = '\\'; break;
|
||||
case '\'': *ptr++ = '\\'; *ptr++ = '\''; break;
|
||||
case '"' : *ptr++ = '\\'; *ptr++ = '"'; break;
|
||||
if ([self length] == 0 ||
|
||||
[self rangeOfCharacterFromSet: quotables].length > 0) {
|
||||
NSString *result;
|
||||
const char *cstring = [self cString];
|
||||
const char *from;
|
||||
char *buf;
|
||||
char *ptr;
|
||||
int len = 0;
|
||||
|
||||
default:
|
||||
if (isprint(*from) || *from == ' ') {
|
||||
*ptr++ = *from;
|
||||
}
|
||||
else {
|
||||
sprintf(ptr, "\\%03o", *(unsigned char*)from);
|
||||
ptr = &ptr[4];
|
||||
}
|
||||
break;
|
||||
for (from = cstring; *from; from++) {
|
||||
switch (*from) {
|
||||
case '\a':
|
||||
case '\b':
|
||||
case '\t':
|
||||
case '\r':
|
||||
case '\n':
|
||||
case '\v':
|
||||
case '\f':
|
||||
case '\\':
|
||||
case '\'' :
|
||||
case '"' :
|
||||
len += 2;
|
||||
break;
|
||||
|
||||
default:
|
||||
if (isprint(*from) || *from == ' ') {
|
||||
len++;
|
||||
}
|
||||
else {
|
||||
len += 4;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
buf = objc_malloc(len + 3);
|
||||
ptr = buf;
|
||||
*ptr++ = '"';
|
||||
for (from = cstring; *from; from++) {
|
||||
switch (*from) {
|
||||
case '\a': *ptr++ = '\\'; *ptr++ = 'a'; break;
|
||||
case '\b': *ptr++ = '\\'; *ptr++ = 'b'; break;
|
||||
case '\t': *ptr++ = '\\'; *ptr++ = 't'; break;
|
||||
case '\r': *ptr++ = '\\'; *ptr++ = 'r'; break;
|
||||
case '\n': *ptr++ = '\\'; *ptr++ = 'n'; break;
|
||||
case '\v': *ptr++ = '\\'; *ptr++ = 'v'; break;
|
||||
case '\f': *ptr++ = '\\'; *ptr++ = 'f'; break;
|
||||
case '\\': *ptr++ = '\\'; *ptr++ = '\\'; break;
|
||||
case '\'': *ptr++ = '\\'; *ptr++ = '\''; break;
|
||||
case '"' : *ptr++ = '\\'; *ptr++ = '"'; break;
|
||||
|
||||
default:
|
||||
if (isprint(*from) || *from == ' ') {
|
||||
*ptr++ = *from;
|
||||
}
|
||||
else {
|
||||
sprintf(ptr, "\\%03o", *(unsigned char*)from);
|
||||
ptr = &ptr[4];
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
*ptr++ = '"';
|
||||
*ptr = '\0';
|
||||
result = [NSString stringWithCString: buf];
|
||||
objc_free(buf);
|
||||
return result;
|
||||
}
|
||||
*ptr++ = '"';
|
||||
*ptr = '\0';
|
||||
[MallocAddress autoreleaseMallocAddress: buf];
|
||||
return buf;
|
||||
return self;
|
||||
}
|
||||
// #endif /* NO_GNUSTEP */
|
||||
|
||||
|
|
387
Source/NSTask.m
Normal file
387
Source/NSTask.m
Normal file
|
@ -0,0 +1,387 @@
|
|||
/* Implementation for NSTask for GNUStep
|
||||
Copyright (C) 1998 Free Software Foundation, Inc.
|
||||
|
||||
Written by: Richard Frith-Macdonald <richard@brainstorm.co.uk>
|
||||
Date: 1998
|
||||
|
||||
This file is part of the GNUstep Base Library.
|
||||
|
||||
This library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Library General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2 of the License, or (at your option) any later version.
|
||||
|
||||
This library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Library General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Library General Public
|
||||
License along with this library; if not, write to the Free
|
||||
Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
|
||||
#include <config.h>
|
||||
#include <gnustep/base/preface.h>
|
||||
#include <Foundation/NSObject.h>
|
||||
#include <Foundation/NSData.h>
|
||||
#include <Foundation/NSDate.h>
|
||||
#include <Foundation/NSString.h>
|
||||
#include <Foundation/NSException.h>
|
||||
#include <Foundation/NSFileHandle.h>
|
||||
#include <Foundation/NSFileManager.h>
|
||||
#include <Foundation/NSProcessInfo.h>
|
||||
#include <Foundation/NSRunLoop.h>
|
||||
#include <Foundation/NSNotification.h>
|
||||
#include <Foundation/NSNotificationQueue.h>
|
||||
#include <Foundation/NSTask.h>
|
||||
|
||||
#include <sys/signal.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/wait.h>
|
||||
|
||||
NSString *NSTaskDidTerminateNotification = @"NSTaskDidTerminateNotification";
|
||||
|
||||
@interface NSTask (Private)
|
||||
- (void) _collectChild;
|
||||
- (void) _sendNotification;
|
||||
@end
|
||||
|
||||
@implementation NSTask
|
||||
|
||||
+ (NSTask*)launchedTaskWithLaunchPath:(NSString*)path arguments: (NSArray*)args
|
||||
{
|
||||
NSTask* task = [NSTask new];
|
||||
|
||||
[task setLaunchPath: path];
|
||||
[task setArguments: args];
|
||||
[task launch];
|
||||
return [task autorelease];
|
||||
}
|
||||
|
||||
- (void) dealloc
|
||||
{
|
||||
[arguments release];
|
||||
[environment release];
|
||||
[launchPath release];
|
||||
[currentDirectoryPath release];
|
||||
[standardError release];
|
||||
[standardInput release];
|
||||
[standardOutput release];
|
||||
[super dealloc];
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Querying task parameters.
|
||||
*/
|
||||
|
||||
- (NSArray*) arguments
|
||||
{
|
||||
return arguments;
|
||||
}
|
||||
|
||||
- (NSString*) currentDirectoryPath
|
||||
{
|
||||
if (currentDirectoryPath == nil) {
|
||||
[self setCurrentDirectoryPath:
|
||||
[[NSFileManager defaultManager] currentDirectoryPath]];
|
||||
}
|
||||
return currentDirectoryPath;
|
||||
}
|
||||
|
||||
- (NSDictionary*) environment
|
||||
{
|
||||
if (environment == nil) {
|
||||
[self setEnvironment: [[NSProcessInfo processInfo] environment]];
|
||||
}
|
||||
return environment;
|
||||
}
|
||||
|
||||
- (NSString*) launchPath
|
||||
{
|
||||
return launchPath;
|
||||
}
|
||||
|
||||
- (NSFileHandle*) standardError
|
||||
{
|
||||
if (standardError == nil) {
|
||||
[self setStandardError: [NSFileHandle fileHandleWithStandardError]];
|
||||
}
|
||||
return standardError;
|
||||
}
|
||||
|
||||
- (NSFileHandle*) standardInput
|
||||
{
|
||||
if (standardInput == nil) {
|
||||
[self setStandardInput: [NSFileHandle fileHandleWithStandardInput]];
|
||||
}
|
||||
return standardInput;
|
||||
}
|
||||
|
||||
- (NSFileHandle*) standardOutput
|
||||
{
|
||||
if (standardOutput == nil) {
|
||||
[self setStandardOutput: [NSFileHandle fileHandleWithStandardOutput]];
|
||||
}
|
||||
return standardOutput;
|
||||
}
|
||||
|
||||
/*
|
||||
* Setting task parameters.
|
||||
*/
|
||||
|
||||
- (void)setArguments: (NSArray*)args
|
||||
{
|
||||
if (hasLaunched) {
|
||||
[NSException raise: NSInvalidArgumentException
|
||||
format: @"NSTask - task has been launched"];
|
||||
}
|
||||
[args retain];
|
||||
[arguments release];
|
||||
arguments = args;
|
||||
}
|
||||
|
||||
- (void)setCurrentDirectoryPath: (NSString*)path
|
||||
{
|
||||
if (hasLaunched) {
|
||||
[NSException raise: NSInvalidArgumentException
|
||||
format: @"NSTask - task has been launched"];
|
||||
}
|
||||
[path retain];
|
||||
[currentDirectoryPath release];
|
||||
currentDirectoryPath = path;
|
||||
}
|
||||
|
||||
- (void)setEnvironment: (NSDictionary*)env
|
||||
{
|
||||
if (hasLaunched) {
|
||||
[NSException raise: NSInvalidArgumentException
|
||||
format: @"NSTask - task has been launched"];
|
||||
}
|
||||
[env retain];
|
||||
[environment release];
|
||||
environment = env;
|
||||
}
|
||||
|
||||
- (void)setLaunchPath: (NSString*)path
|
||||
{
|
||||
if (hasLaunched) {
|
||||
[NSException raise: NSInvalidArgumentException
|
||||
format: @"NSTask - task has been launched"];
|
||||
}
|
||||
[path retain];
|
||||
[launchPath release];
|
||||
launchPath = path;
|
||||
}
|
||||
|
||||
- (void)setStandardError: (NSFileHandle*)hdl
|
||||
{
|
||||
if (hasLaunched) {
|
||||
[NSException raise: NSInvalidArgumentException
|
||||
format: @"NSTask - task has been launched"];
|
||||
}
|
||||
[hdl retain];
|
||||
[standardError release];
|
||||
standardError = hdl;
|
||||
}
|
||||
|
||||
- (void)setStandardInput: (NSFileHandle*)hdl
|
||||
{
|
||||
if (hasLaunched) {
|
||||
[NSException raise: NSInvalidArgumentException
|
||||
format: @"NSTask - task has been launched"];
|
||||
}
|
||||
[hdl retain];
|
||||
[standardInput release];
|
||||
standardInput = hdl;
|
||||
}
|
||||
|
||||
- (void)setStandardOutput: (NSFileHandle*)hdl
|
||||
{
|
||||
if (hasLaunched) {
|
||||
[NSException raise: NSInvalidArgumentException
|
||||
format: @"NSTask - task has been launched"];
|
||||
}
|
||||
[hdl retain];
|
||||
[standardOutput release];
|
||||
standardOutput = hdl;
|
||||
}
|
||||
|
||||
/*
|
||||
* Obtaining task state
|
||||
*/
|
||||
|
||||
- (BOOL) isRunning
|
||||
{
|
||||
if (hasLaunched == NO) return NO;
|
||||
if (hasCollected == NO) {
|
||||
[self _collectChild];
|
||||
}
|
||||
if (hasTerminated == NO) return NO;
|
||||
return YES;
|
||||
}
|
||||
|
||||
- (int) terminationStatus
|
||||
{
|
||||
if (hasLaunched == NO) {
|
||||
[NSException raise: NSInvalidArgumentException
|
||||
format: @"NSTask - task has not yet launched"];
|
||||
}
|
||||
if (hasCollected == NO) {
|
||||
[self _collectChild];
|
||||
}
|
||||
if (hasTerminated) {
|
||||
[NSException raise: NSInvalidArgumentException
|
||||
format: @"NSTask - task has not yet terminated"];
|
||||
}
|
||||
return terminationStatus;
|
||||
}
|
||||
|
||||
/*
|
||||
* Handling a task.
|
||||
*/
|
||||
- (void) interrupt
|
||||
{
|
||||
}
|
||||
|
||||
- (void) launch
|
||||
{
|
||||
int pid;
|
||||
const char* executable;
|
||||
const char* path;
|
||||
int idesc;
|
||||
int odesc;
|
||||
int edesc;
|
||||
NSDictionary *e = [self environment];
|
||||
NSArray *k = [e allKeys];
|
||||
NSArray *a = [self arguments];
|
||||
int ec = [e count];
|
||||
int ac = [a count];
|
||||
const char *args[ac+2];
|
||||
const char *envp[ec+1];
|
||||
int i;
|
||||
|
||||
if (hasLaunched) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (launchPath == nil) {
|
||||
[NSException raise: NSInvalidArgumentException
|
||||
format: @"NSTask - no launch path set"];
|
||||
}
|
||||
else if ([[NSFileManager defaultManager] isExecutableFileAtPath:
|
||||
launchPath] == NO) {
|
||||
[NSException raise: NSInvalidArgumentException
|
||||
format: @"NSTask - launch path is not valid"];
|
||||
}
|
||||
|
||||
executable = [[self launchPath] cString];
|
||||
|
||||
args[0] = [[[self launchPath] lastPathComponent] cString];
|
||||
for (i = 0; i < ac; i++) {
|
||||
args[i+1] = [[[a objectAtIndex: i] description] cString];
|
||||
}
|
||||
args[ac+1] = 0;
|
||||
|
||||
for (i = 0; i < ec; i++) {
|
||||
NSString *s;
|
||||
id key = [k objectAtIndex: i];
|
||||
id val = [e objectForKey: k];
|
||||
|
||||
s = [NSString stringWithFormat: @"%s=%s", [key cString], [val cString]];
|
||||
envp[i] = [s cString];
|
||||
}
|
||||
envp[ec] = 0;
|
||||
|
||||
path = [[self currentDirectoryPath] cString];
|
||||
idesc = [[self standardInput] fileDescriptor];
|
||||
odesc = [[self standardError] fileDescriptor];
|
||||
edesc = [[self standardOutput] fileDescriptor];
|
||||
|
||||
pid = fork();
|
||||
if (pid < 0) {
|
||||
[NSException raise: NSInvalidArgumentException
|
||||
format: @"NSTask - failed to create child process"];
|
||||
}
|
||||
if (pid == 0) {
|
||||
if (idesc != 0) dup2(idesc, 0);
|
||||
if (odesc != 1) dup2(odesc, 1);
|
||||
if (edesc != 2) dup2(edesc, 2);
|
||||
chdir(path);
|
||||
execve(executable, args, envp);
|
||||
exit(-1);
|
||||
}
|
||||
else {
|
||||
taskId = pid;
|
||||
hasLaunched = YES;
|
||||
}
|
||||
}
|
||||
|
||||
- (void) terminate
|
||||
{
|
||||
if (hasLaunched == NO) {
|
||||
[NSException raise: NSInvalidArgumentException
|
||||
format: @"NSTask - task has not yet launched"];
|
||||
}
|
||||
if (hasTerminated) {
|
||||
return;
|
||||
}
|
||||
|
||||
hasTerminated = YES;
|
||||
killpg(taskId, SIGTERM);
|
||||
|
||||
if (hasNotified == NO) {
|
||||
[self _sendNotification];
|
||||
}
|
||||
}
|
||||
|
||||
- (void) waitUntilExit
|
||||
{
|
||||
while ([self isRunning]) {
|
||||
NSDate *limit;
|
||||
|
||||
/*
|
||||
* Poll at 1.0 second intervals.
|
||||
*/
|
||||
limit = [[NSDate alloc] initWithTimeIntervalSinceNow: 1.0];
|
||||
[[NSRunLoop currentRunLoop] runMode: NSDefaultRunLoopMode
|
||||
beforeDate: nil];
|
||||
[limit release];
|
||||
}
|
||||
}
|
||||
@end
|
||||
|
||||
@implementation NSTask (Private)
|
||||
|
||||
- (void) _collectChild
|
||||
{
|
||||
if (hasCollected == NO) {
|
||||
if (waitpid(taskId, &terminationStatus, WNOHANG) == taskId) {
|
||||
hasCollected = YES;
|
||||
hasTerminated = YES;
|
||||
if (hasNotified == NO) {
|
||||
[self _sendNotification];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
- (void) _sendNotification
|
||||
{
|
||||
if (hasNotified == NO) {
|
||||
NSNotification *n;
|
||||
|
||||
hasNotified = YES;
|
||||
n = [NSNotification notificationWithName: NSTaskDidTerminateNotification
|
||||
object: self
|
||||
userInfo: nil];
|
||||
|
||||
[[NSNotificationQueue defaultQueue] enqueueNotification: n
|
||||
postingStyle: NSPostASAP
|
||||
coalesceMask: NSNotificationNoCoalescing
|
||||
forModes: nil];
|
||||
}
|
||||
}
|
||||
@end
|
||||
|
|
@ -1005,6 +1005,10 @@ static NSMapTable* port_number_2_port;
|
|||
initForReceivingWithCapacity: packet_size
|
||||
receivingInPort: self
|
||||
replyOutPort: reply_port];
|
||||
if (packet == nil)
|
||||
[NSException raise: NSInternalInconsistencyException
|
||||
format: @"[TcpInPort _tryToGetPacketFromReadableFD:"
|
||||
@" - failed to create incoming packet"];
|
||||
NSMapInsert(_client_sock_2_packet,(void*)fd_index,(void*)packet);
|
||||
}
|
||||
/* The packet has now been created with correct capacity */
|
||||
|
|
|
@ -35,11 +35,18 @@
|
|||
#include <Foundation/NSNotificationQueue.h>
|
||||
#include <Foundation/NSHost.h>
|
||||
|
||||
#ifdef WIN32
|
||||
#include <Windows32/Sockets.h>
|
||||
#else
|
||||
#include <sys/param.h>
|
||||
#include <sys/socket.h>
|
||||
#include <netinet/in.h>
|
||||
#include <arpa/inet.h>
|
||||
#endif /* WIN32 */
|
||||
|
||||
#include <sys/file.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/socket.h>
|
||||
#include <sys/fcntl.h>
|
||||
#include <netinet/in.h>
|
||||
#include <arpa/inet.h>
|
||||
#include <netdb.h>
|
||||
#include <unistd.h>
|
||||
|
@ -65,6 +72,12 @@ static UnixFileHandle* fh_stderr = nil;
|
|||
// Key to info dictionary for operation mode.
|
||||
static NSString* NotificationKey = @"NSFileHandleNotificationKey";
|
||||
|
||||
@interface UnixFileHandle (Private)
|
||||
- (void) setAddr: (struct sockaddr_in *)sin;
|
||||
@end
|
||||
|
||||
@implementation UnixFileHandle
|
||||
|
||||
static BOOL
|
||||
getAddr(NSString* name, NSString* svc, NSString* pcl, struct sockaddr_in *sin)
|
||||
{
|
||||
|
@ -95,7 +108,7 @@ getAddr(NSString* name, NSString* svc, NSString* pcl, struct sockaddr_in *sin)
|
|||
#ifndef HAVE_INET_ATON
|
||||
sin->sin_addr.s_addr = inet_addr([name cStringNoCopy]);
|
||||
#else
|
||||
if (inet_aton([name cStringNoCopy], &sin->sin_addr.s_addr) == 0)
|
||||
if (inet_aton([name cStringNoCopy], &sin->sin_addr) == 0)
|
||||
return NO;
|
||||
#endif
|
||||
}
|
||||
|
@ -127,9 +140,6 @@ getAddr(NSString* name, NSString* svc, NSString* pcl, struct sockaddr_in *sin)
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
@implementation UnixFileHandle
|
||||
|
||||
+ allocWithZone:(NSZone*)z
|
||||
{
|
||||
return NSAllocateObject ([self class], 0, z);
|
||||
|
@ -137,6 +147,10 @@ getAddr(NSString* name, NSString* svc, NSString* pcl, struct sockaddr_in *sin)
|
|||
|
||||
- (void)dealloc
|
||||
{
|
||||
[address release];
|
||||
[service release];
|
||||
[protocol release];
|
||||
|
||||
if (self == fh_stdin)
|
||||
fh_stdin = nil;
|
||||
if (self == fh_stdout)
|
||||
|
@ -169,15 +183,15 @@ getAddr(NSString* name, NSString* svc, NSString* pcl, struct sockaddr_in *sin)
|
|||
return [self initWithNullDevice];
|
||||
}
|
||||
|
||||
- (id)initAsClientAtAddress:address
|
||||
service:service
|
||||
protocol:protocol
|
||||
- (id)initAsClientAtAddress:a
|
||||
service:s
|
||||
protocol:p
|
||||
forModes:modes
|
||||
{
|
||||
int net;
|
||||
struct sockaddr_in sin;
|
||||
|
||||
if (getAddr(address, service, protocol, &sin) == NO)
|
||||
if (getAddr(a, s, p, &sin) == NO)
|
||||
{
|
||||
[self dealloc];
|
||||
NSLog(@"bad address-service-protocol combination");
|
||||
|
@ -217,19 +231,21 @@ getAddr(NSString* name, NSString* svc, NSString* pcl, struct sockaddr_in *sin)
|
|||
connectOK = YES;
|
||||
readOK = NO;
|
||||
writeOK = NO;
|
||||
[self setAddr: &sin];
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
- (id)initAsServerAtAddress:address
|
||||
service:service
|
||||
protocol:protocol
|
||||
- (id)initAsServerAtAddress:a
|
||||
service:s
|
||||
protocol:p
|
||||
{
|
||||
int status = 1;
|
||||
int net;
|
||||
struct sockaddr_in sin;
|
||||
int size = sizeof(sin);
|
||||
|
||||
if (getAddr(address, service, protocol, &sin) == NO)
|
||||
if (getAddr(a, s, p, &sin) == NO)
|
||||
{
|
||||
[self dealloc];
|
||||
NSLog(@"bad address-service-protocol combination");
|
||||
|
@ -261,12 +277,15 @@ getAddr(NSString* name, NSString* svc, NSString* pcl, struct sockaddr_in *sin)
|
|||
return nil;
|
||||
}
|
||||
|
||||
getsockname(net, (struct sockaddr*)&sin, &size);
|
||||
|
||||
self = [self initWithFileDescriptor:net closeOnDealloc:YES];
|
||||
if (self)
|
||||
{
|
||||
acceptOK = YES;
|
||||
readOK = NO;
|
||||
writeOK = NO;
|
||||
[self setAddr: &sin];
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
@ -1021,9 +1040,15 @@ getAddr(NSString* name, NSString* svc, NSString* pcl, struct sockaddr_in *sin)
|
|||
[readInfo setObject:s forKey:GSFileHandleNotificationError];
|
||||
}
|
||||
else { // Accept attempt completed.
|
||||
hdl = [[NSFileHandle alloc] initWithFileDescriptor:desc];
|
||||
[readInfo setObject:hdl forKey:NSFileHandleNotificationFileHandleItem];
|
||||
[hdl release];
|
||||
UnixFileHandle *h;
|
||||
struct sockaddr_in sin;
|
||||
int size = sizeof(sin);
|
||||
|
||||
h = [[UnixFileHandle alloc] initWithFileDescriptor:desc];
|
||||
getsockname(desc, (struct sockaddr*)&sin, &size);
|
||||
[h setAddr: &sin];
|
||||
[readInfo setObject: h forKey: NSFileHandleNotificationFileHandleItem];
|
||||
[h release];
|
||||
}
|
||||
[self postReadNotification];
|
||||
}
|
||||
|
@ -1110,6 +1135,15 @@ getAddr(NSString* name, NSString* svc, NSString* pcl, struct sockaddr_in *sin)
|
|||
return nil; /* Don't restart timed out events */
|
||||
}
|
||||
|
||||
- (void) setAddr: (struct sockaddr_in *)sin
|
||||
{
|
||||
address = [NSString stringWithCString: inet_ntoa(sin->sin_addr)];
|
||||
[address retain];
|
||||
service = [NSString stringWithFormat: @"%d", (int)ntohs(sin->sin_port)];
|
||||
[service retain];
|
||||
protocol = @"tcp";
|
||||
}
|
||||
|
||||
- (void)setNonBlocking:(BOOL)flag
|
||||
{
|
||||
int e;
|
||||
|
@ -1139,5 +1173,21 @@ getAddr(NSString* name, NSString* svc, NSString* pcl, struct sockaddr_in *sin)
|
|||
NSLog(@"unable to get non-blocking mode - %s", strerror(errno));
|
||||
}
|
||||
|
||||
- (NSString*) socketAddress
|
||||
{
|
||||
return address;
|
||||
}
|
||||
|
||||
- (NSString*) socketProtocol
|
||||
{
|
||||
return protocol;
|
||||
}
|
||||
|
||||
- (NSString*) socketService
|
||||
{
|
||||
return service;
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
|
||||
|
|
|
@ -63,14 +63,16 @@ initWithCapacity:1] autorelease];
|
|||
|
||||
dictionary: '{' keyval_list '}'
|
||||
{$$ = $2;}
|
||||
| '{' keyval_list ';' '}'
|
||||
{$$ = $2;}
|
||||
| '{' '}'
|
||||
{$$ = [NSDictionary dictionary];}
|
||||
;
|
||||
keyval_list: keyval_list keyval_pair
|
||||
keyval_list: keyval_list ';' keyval_pair
|
||||
{
|
||||
$$ = $1;
|
||||
[$$ addEntriesFromDictionary:$2];
|
||||
[$2 release];
|
||||
[$$ addEntriesFromDictionary:$3];
|
||||
[$3 release];
|
||||
}
|
||||
| keyval_pair
|
||||
{
|
||||
|
@ -78,7 +80,7 @@ keyval_list: keyval_list keyval_pair
|
|||
[$$ autorelease];
|
||||
}
|
||||
;
|
||||
keyval_pair: NSSTRING '=' object ';'
|
||||
keyval_pair: NSSTRING '=' object
|
||||
{
|
||||
$$ = [[NSMutableDictionary alloc]
|
||||
initWithCapacity:1];
|
||||
|
|
|
@ -41,6 +41,10 @@ asignment: value EQUALS value SEMICOLEN
|
|||
{
|
||||
[(NSMutableDictionary *)properties setObject: $3 forKey: (NSString *) $1];
|
||||
}
|
||||
| value SEMICOLEN
|
||||
{
|
||||
[(NSMutableDictionary *)properties setObject: nil forKey: (NSString *) $1];
|
||||
}
|
||||
;
|
||||
|
||||
value: LABEL
|
||||
|
|
|
@ -62,6 +62,7 @@ nshashtable \
|
|||
tcpport-server \
|
||||
tcpport-client \
|
||||
nsnotification \
|
||||
nstask \
|
||||
nstimer \
|
||||
coder \
|
||||
cstream \
|
||||
|
@ -109,6 +110,7 @@ nshashtable_OBJC_FILES = nshashtable.m
|
|||
tcpport-server_OBJC_FILES = tcpport-server.m
|
||||
tcpport-client_OBJC_FILES = tcpport-client.m
|
||||
nsnotification_OBJC_FILES = nsnotification.m
|
||||
nstask_OBJC_FILES = nstask.m
|
||||
nstimer_OBJC_FILES = nstimer.m
|
||||
coder_OBJC_FILES = coder.m
|
||||
cstream_OBJC_FILES = cstream.m
|
||||
|
|
|
@ -138,6 +138,66 @@ main()
|
|||
minutes:0 seconds:0 sinceDate:momsBDay];
|
||||
printf("%d, %d\n", months, days);
|
||||
}
|
||||
|
||||
printf("\nY2K checks\n");
|
||||
c = [NSCalendarDate dateWithString: @"1999-12-31 23:59:59"
|
||||
calendarFormat: @"%Y-%m-%d %H:%M:%S"];
|
||||
printf("Start at %s\n", [[c description] cString]);
|
||||
c = [c addYear:0 month:0 day:0 hour:0 minute:0 second:1];
|
||||
printf("Add one second - %s\n", [[c description] cString]);
|
||||
c = [c addYear:0 month:0 day:0 hour:0 minute:0 second:1];
|
||||
printf("Add another second - %s\n", [[c description] cString]);
|
||||
c = [c addYear:0 month:0 day:0 hour:1 minute:0 second:0];
|
||||
printf("Add an hour - %s\n", [[c description] cString]);
|
||||
c = [c addYear:0 month:0 day:0 hour:-2 minute:0 second:0];
|
||||
printf("Subtract two hours - %s\n", [[c description] cString]);
|
||||
|
||||
printf("\nY2K is a leap year checks\n");
|
||||
c = [NSCalendarDate dateWithString: @"2000-2-28 23:59:59"
|
||||
calendarFormat: @"%Y-%m-%d %H:%M:%S"];
|
||||
printf("Start at %s\n", [[c description] cString]);
|
||||
c = [c addYear:0 month:0 day:0 hour:0 minute:0 second:1];
|
||||
printf("Add one second - %s\n", [[c description] cString]);
|
||||
c = [c addYear:0 month:0 day:0 hour:0 minute:0 second:1];
|
||||
printf("Add another second - %s\n", [[c description] cString]);
|
||||
c = [c addYear:0 month:0 day:0 hour:1 minute:0 second:0];
|
||||
printf("Add an hour - %s\n", [[c description] cString]);
|
||||
c = [c addYear:0 month:0 day:0 hour:-2 minute:0 second:0];
|
||||
printf("Subtract two hours - %s\n", [[c description] cString]);
|
||||
c = [c addYear:0 month:0 day:0 hour:5 minute:0 second:0];
|
||||
printf("Add five hours - %s\n", [[c description] cString]);
|
||||
c = [c addYear:1 month:0 day:0 hour:0 minute:0 second:0];
|
||||
printf("Add one year - %s\n", [[c description] cString]);
|
||||
c = [c addYear:0 month:0 day:-1 hour:0 minute:0 second:0];
|
||||
printf("Subtract one day - %s\n", [[c description] cString]);
|
||||
c = [c addYear:1 month:0 day:1 hour:0 minute:0 second:0];
|
||||
printf("Add a year and a day - %s\n", [[c description] cString]);
|
||||
|
||||
printf("\n2004 is a leap year checks\n");
|
||||
c = [NSCalendarDate dateWithString: @"2004-2-28 23:59:59"
|
||||
calendarFormat: @"%Y-%m-%d %H:%M:%S"];
|
||||
printf("Start at %s\n", [[c description] cString]);
|
||||
c = [c addYear:0 month:0 day:0 hour:0 minute:0 second:1];
|
||||
printf("Add one second - %s\n", [[c description] cString]);
|
||||
c = [c addYear:0 month:0 day:0 hour:0 minute:0 second:1];
|
||||
printf("Add another second - %s\n", [[c description] cString]);
|
||||
c = [c addYear:0 month:0 day:0 hour:1 minute:0 second:0];
|
||||
printf("Add an hour - %s\n", [[c description] cString]);
|
||||
c = [c addYear:0 month:0 day:0 hour:-2 minute:0 second:0];
|
||||
printf("Subtract two hours - %s\n", [[c description] cString]);
|
||||
|
||||
printf("\n2100 is NOT a leap year checks\n");
|
||||
c = [NSCalendarDate dateWithString: @"2100-2-28 23:59:59"
|
||||
calendarFormat: @"%Y-%m-%d %H:%M:%S"];
|
||||
printf("Start at %s\n", [[c description] cString]);
|
||||
c = [c addYear:0 month:0 day:0 hour:0 minute:0 second:1];
|
||||
printf("Add one second - %s\n", [[c description] cString]);
|
||||
c = [c addYear:0 month:0 day:0 hour:0 minute:0 second:1];
|
||||
printf("Add another second - %s\n", [[c description] cString]);
|
||||
c = [c addYear:0 month:0 day:0 hour:1 minute:0 second:0];
|
||||
printf("Add an hour - %s\n", [[c description] cString]);
|
||||
c = [c addYear:0 month:0 day:0 hour:-2 minute:0 second:0];
|
||||
printf("Subtract two hours - %s\n", [[c description] cString]);
|
||||
}
|
||||
|
||||
[pool release];
|
||||
|
|
|
@ -26,11 +26,12 @@ GNUSTEP_INSTALLATION_DIR = $(GNUSTEP_SYSTEM_ROOT)
|
|||
include $(GNUSTEP_SYSTEM_ROOT)/Makefiles/common.make
|
||||
|
||||
# The application to be compiled
|
||||
TOOL_NAME = dread dwrite dremove
|
||||
TOOL_NAME = defaults dread dwrite dremove
|
||||
OBJC_PROGRAM_NAME = gdomap
|
||||
|
||||
# The source files to be compiled
|
||||
gdomap_C_FILES = gdomap.c
|
||||
defaults_OBJC_FILES = defaults.m
|
||||
dread_OBJC_FILES = dread.m
|
||||
dremove_OBJC_FILES = dremove.m
|
||||
dwrite_OBJC_FILES = dwrite.m
|
||||
|
|
622
Tools/defaults.m
Normal file
622
Tools/defaults.m
Normal file
|
@ -0,0 +1,622 @@
|
|||
/* This tool mimics the OPENSTEP command line tool for handling defaults.
|
||||
Copyright (C) 1997 Free Software Foundation, Inc.
|
||||
|
||||
Written by: Richard Frith-Macdonald <richard@brainstorm.co.uk>
|
||||
Created: January 1998
|
||||
|
||||
This file is part of the GNUstep Base Library.
|
||||
|
||||
This library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Library General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
version 2 of the License, or (at your option) any later version.
|
||||
|
||||
This library is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Library General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Library General Public
|
||||
License along with this library; if not, write to the Free
|
||||
Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
|
||||
#include <Foundation/NSArray.h>
|
||||
#include <Foundation/NSDictionary.h>
|
||||
#include <Foundation/NSString.h>
|
||||
#include <Foundation/NSProcessInfo.h>
|
||||
#include <Foundation/NSUserDefaults.h>
|
||||
#include <Foundation/NSDebug.h>
|
||||
|
||||
|
||||
int
|
||||
main(int argc, char** argv)
|
||||
{
|
||||
NSUserDefaults *defs;
|
||||
NSProcessInfo *proc;
|
||||
NSArray *args;
|
||||
NSArray *domains;
|
||||
NSMutableDictionary *domain;
|
||||
NSString *owner = nil;
|
||||
NSString *name = nil;
|
||||
NSString *value;
|
||||
NSString *user = nil;
|
||||
BOOL found = NO;
|
||||
int i;
|
||||
|
||||
[NSObject enableDoubleReleaseCheck: YES];
|
||||
|
||||
proc = [NSProcessInfo processInfo];
|
||||
if (proc == nil) {
|
||||
NSLog(@"defaults: unable to get process information!\n");
|
||||
exit(0);
|
||||
}
|
||||
|
||||
args = [proc arguments];
|
||||
|
||||
for (i = 0; i < [args count]; i++) {
|
||||
if ([[args objectAtIndex: i] isEqual: @"--help"] ||
|
||||
[[args objectAtIndex: i] isEqual: @"help"]) {
|
||||
printf(
|
||||
"The 'defaults' command lets you to read and modify a user's defaults.\n\n"
|
||||
"This program replaces the old NeXTstep style dread, dwrite, and dremove\n"
|
||||
"programs.\n\n"
|
||||
"If you have access to another user's defaults database, you may include\n"
|
||||
"'-u username' before any other options to use that user's database rather\n"
|
||||
"than your own.\n\n");
|
||||
printf(
|
||||
"defaults read [ domain [ key] ]\n"
|
||||
" read the named default from the specified domain.\n"
|
||||
" If no 'key' is given - read all defaults from the domain.\n"
|
||||
" If no 'domain' is given - read all defaults from all domains.\n\n");
|
||||
printf(
|
||||
"defaults readkey key\n"
|
||||
" read the named default from all domains.\n\n");
|
||||
printf(
|
||||
"defaults write domain key value\n"
|
||||
" write 'value' as default 'key' in the specified domain.\n"
|
||||
" 'value' must be a property list in single quotes.\n\n");
|
||||
printf(
|
||||
"defaults write domain dictionary\n"
|
||||
" write 'dictionary' as a replacement for the specified domain.\n"
|
||||
" 'dictionary' must be a property list in single quotes.\n\n");
|
||||
printf(
|
||||
"defaults write\n"
|
||||
" reads standard input for defaults in the format produced by\n"
|
||||
" 'defaults read' and writes them to the database.\n\n");
|
||||
printf(
|
||||
"defaults delete [ domain [ key] ]\n"
|
||||
" remove the specified default(s) from the domain.\n"
|
||||
" If no 'key' is given - delete the entire domain.\n\n");
|
||||
printf(
|
||||
"defaults delete\n"
|
||||
" read standard input for a series of lines containing pairs of domains\n"
|
||||
" and keys for defaults to be deleted.\n\n");
|
||||
printf(
|
||||
"defaults domains\n"
|
||||
" lists the domains in the database (one per line)\n\n");
|
||||
printf(
|
||||
"defaults find word\n"
|
||||
" searches domain names, default names, and default value strings for\n"
|
||||
" those equal to the specified word and lists them on standard output.\n\n");
|
||||
printf(
|
||||
"defaults plist\n"
|
||||
" output some information about property lists\n\n");
|
||||
printf(
|
||||
"defaults help\n"
|
||||
" list options fo the defaults command.\n\n");
|
||||
exit(0);
|
||||
}
|
||||
else if ([[args objectAtIndex: i] isEqual: @"plist"]) {
|
||||
printf(
|
||||
"A property list is a method of providing structured information consisting\n"
|
||||
"of strings, arrays, dictionaries, and binary data.\n\n"
|
||||
"The defaults system allows you to work with a human-readable form of a
|
||||
property list which is set as the value of a default.\n\n");
|
||||
printf(
|
||||
"In a property list, strings appear as plain text (as long as they contain\n"
|
||||
"no special characters), and inside quotation marks otherwise.\n"
|
||||
"Special characters inside a quoted string are 'escaped' by a backslash.\n"
|
||||
"This escape mechanism is used to permit the double quote mark to appear\n"
|
||||
"inside a quoted string.\n"
|
||||
"Arrays appear as a comma separated list of items delimited by brakets.\n"
|
||||
"Dictionaries appear as a series of key-value pairs, each pair is followed\n"
|
||||
"by a semicolon and the whole dictionary is delimited by curly brackets.\n"
|
||||
"Data is encoded as hexadecimal digits delimited by angle brackets.\n\n");
|
||||
printf(
|
||||
"In output from 'defaults read' the defaults values are represented as\n"
|
||||
"property lists enclosed in single quotes. If a value actually contains\n"
|
||||
"a string with a single quite mark in it, that quote is repeated.\n"
|
||||
"Similarly, if 'defaults write' is reading a defaults value from stdin\n"
|
||||
"it expects to receive the value in single quotes with any internal\n"
|
||||
"single quote marks repeated.\n\n");
|
||||
printf(
|
||||
"Here is an example of a dictionary encoded as a text property list -\n\n");
|
||||
printf(
|
||||
"{\n"
|
||||
" Name = \"My Application\";\n"
|
||||
" Author = \"Just me and \\\"my other half\\\"\";\n"
|
||||
" Modules = (\n"
|
||||
" Main,\n"
|
||||
" \"'Input output'\",\n"
|
||||
" Computation\n"
|
||||
" );\n"
|
||||
" Checksum = <01014b5b 123a8b20>\n"
|
||||
"}\n\n");
|
||||
printf(
|
||||
"And as output from the command 'defaults read foo bar' -\n\n");
|
||||
printf(
|
||||
"foo bar '{\n"
|
||||
" Name = \"My Application\";\n"
|
||||
" Author = \"Just me and \\\"my other half\\\"\";\n"
|
||||
" Modules = (\n"
|
||||
" Main,\n"
|
||||
" \"''Input output''\",\n"
|
||||
" Computation\n"
|
||||
" );\n"
|
||||
" Checksum = <01014b5b 123a8b20>\n"
|
||||
"}'\n\n");
|
||||
exit(0);
|
||||
}
|
||||
}
|
||||
|
||||
i = 0;
|
||||
if ([args count] <= i) {
|
||||
NSLog(@"defaults: too few arguments supplied!\n");
|
||||
exit(0);
|
||||
}
|
||||
if ([[args objectAtIndex: i] isEqual: @"-u"]) {
|
||||
if ([args count] > ++i) {
|
||||
user = [args objectAtIndex: i++];
|
||||
}
|
||||
else {
|
||||
NSLog(@"defaults: no name supplied for -u option!\n");
|
||||
exit(0);
|
||||
}
|
||||
}
|
||||
if (user) {
|
||||
defs = [[NSUserDefaults alloc] initWithUser: user];
|
||||
}
|
||||
else {
|
||||
defs = [NSUserDefaults standardUserDefaults];
|
||||
}
|
||||
if (defs == nil) {
|
||||
NSLog(@"defaults: unable to access defaults database!\n");
|
||||
exit(0);
|
||||
}
|
||||
/* We don't want this tool in the defaults database - so remove it. */
|
||||
[defs removePersistentDomainForName: [proc processName]];
|
||||
|
||||
if ([args count] <= i) {
|
||||
NSLog(@"defaults: too few arguments supplied!\n");
|
||||
exit(0);
|
||||
}
|
||||
|
||||
if ([[args objectAtIndex: i] isEqual: @"read"] ||
|
||||
[[args objectAtIndex: i] isEqual: @"readkey"]) {
|
||||
if ([[args objectAtIndex: i] isEqual: @"read"]) {
|
||||
if ([args count] == ++i) {
|
||||
name = nil;
|
||||
owner = nil;
|
||||
}
|
||||
else {
|
||||
owner = [args objectAtIndex: i++];
|
||||
if ([args count] > i) {
|
||||
name = [args objectAtIndex: i];
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
if ([args count] == ++i) {
|
||||
NSLog(@"defaults: too few arguments supplied!\n");
|
||||
exit(0);
|
||||
}
|
||||
owner = nil;
|
||||
name = [args objectAtIndex: i];
|
||||
}
|
||||
|
||||
domains = [defs persistentDomainNames];
|
||||
for (i = 0; i < [domains count]; i++) {
|
||||
NSString *domainName = [domains objectAtIndex: i];
|
||||
|
||||
if (owner == nil || [owner isEqual: domainName]) {
|
||||
NSDictionary *dom;
|
||||
|
||||
dom = [defs persistentDomainForName: domainName];
|
||||
if (dom) {
|
||||
if (name == nil) {
|
||||
NSEnumerator *enumerator;
|
||||
NSString *key;
|
||||
|
||||
enumerator = [dom keyEnumerator];
|
||||
while ((key = [enumerator nextObject]) != nil) {
|
||||
id obj = [dom objectForKey: key];
|
||||
const char *ptr;
|
||||
|
||||
printf("%s %s '",
|
||||
[domainName cString], [key cString]);
|
||||
ptr = [[obj description] cString];
|
||||
while (*ptr) {
|
||||
if (*ptr == '\'') {
|
||||
putchar('\'');
|
||||
}
|
||||
putchar(*ptr);
|
||||
ptr++;
|
||||
}
|
||||
printf("'\n");
|
||||
}
|
||||
}
|
||||
else {
|
||||
id obj = [dom objectForKey: name];
|
||||
|
||||
if (obj) {
|
||||
const char *ptr;
|
||||
|
||||
printf("%s %s '",
|
||||
[domainName cString], [name cString]);
|
||||
ptr = [[obj description] cString];
|
||||
while (*ptr) {
|
||||
if (*ptr == '\'') {
|
||||
putchar('\'');
|
||||
}
|
||||
putchar(*ptr);
|
||||
ptr++;
|
||||
}
|
||||
printf("'\n");
|
||||
found = YES;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (found == NO && name != nil) {
|
||||
printf("defaults read: couldn't read default\n");
|
||||
}
|
||||
}
|
||||
else if ([[args objectAtIndex: i] isEqual: @"write"]) {
|
||||
id obj;
|
||||
|
||||
if ([args count] == ++i) {
|
||||
int size = BUFSIZ;
|
||||
char *buf = objc_malloc(size);
|
||||
|
||||
/*
|
||||
* Read from stdin - grow buffer as necessary since defaults
|
||||
* values are quoted property lists which may be huge.
|
||||
*/
|
||||
while (fgets(buf, BUFSIZ, stdin) != 0) {
|
||||
char *ptr;
|
||||
char *start;
|
||||
char *str;
|
||||
|
||||
start = buf;
|
||||
|
||||
/*
|
||||
* Expect domain name as a space delimited string.
|
||||
*/
|
||||
ptr = start;
|
||||
while (*ptr && !isspace(*ptr)) {
|
||||
ptr++;
|
||||
}
|
||||
if (*ptr) {
|
||||
*ptr++ = '\0';
|
||||
}
|
||||
while (isspace(*ptr)) {
|
||||
ptr++;
|
||||
}
|
||||
if (*start == '\0') {
|
||||
printf("defaults write: invalid input - nul domain name\n");
|
||||
exit(0);
|
||||
}
|
||||
for (str = start; *str; str++) {
|
||||
if (isspace(*str)) {
|
||||
printf("defaults write: invalid input - "
|
||||
"space in domain name.\n");
|
||||
exit(0);
|
||||
}
|
||||
}
|
||||
owner = [NSString stringWithCString: start];
|
||||
start = ptr;
|
||||
|
||||
/*
|
||||
* Expect defaults key as a space delimited string.
|
||||
*/
|
||||
ptr = start;
|
||||
while (*ptr && !isspace(*ptr)) {
|
||||
ptr++;
|
||||
}
|
||||
if (*ptr) {
|
||||
*ptr++ = '\0';
|
||||
}
|
||||
while (isspace(*ptr)) {
|
||||
ptr++;
|
||||
}
|
||||
if (*start == '\0') {
|
||||
printf("defaults write: invalid input - "
|
||||
"nul default name.\n");
|
||||
exit(0);
|
||||
}
|
||||
for (str = start; *str; str++) {
|
||||
if (isspace(*str)) {
|
||||
printf("defaults write: invalid input - "
|
||||
"space in default name.\n");
|
||||
exit(0);
|
||||
}
|
||||
}
|
||||
name = [NSString stringWithCString: start];
|
||||
|
||||
/*
|
||||
* Expect defaults value as a quoted property list which
|
||||
* may cover multiple lines.
|
||||
*/
|
||||
start = ptr;
|
||||
if (*start == '\'') {
|
||||
for (ptr = ++start; ; ptr++) {
|
||||
if (*ptr == '\0') {
|
||||
int pos = ptr - buf;
|
||||
|
||||
if (size - pos < BUFSIZ) {
|
||||
char *tmp;
|
||||
int spos = start - buf;
|
||||
|
||||
tmp = objc_realloc(buf, size + BUFSIZ);
|
||||
if (tmp) {
|
||||
size += BUFSIZ;
|
||||
buf = tmp;
|
||||
ptr = &buf[pos];
|
||||
start = &buf[spos];
|
||||
}
|
||||
else {
|
||||
printf("defaults write: fatal error - "
|
||||
"out of memory.\n");
|
||||
exit(0);
|
||||
}
|
||||
}
|
||||
if (fgets(ptr, BUFSIZ, stdin) == 0) {
|
||||
printf("defaults write: invalid input - "
|
||||
"no final quote.\n");
|
||||
exit(0);
|
||||
}
|
||||
}
|
||||
if (*ptr == '\'') {
|
||||
if (ptr[1] == '\'') {
|
||||
strcpy(ptr, &ptr[1]);
|
||||
}
|
||||
else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
ptr = start;
|
||||
while (*ptr && !isspace(*ptr)) {
|
||||
ptr++;
|
||||
}
|
||||
}
|
||||
if (*ptr) {
|
||||
*ptr++ = '\0';
|
||||
}
|
||||
if (*start == '\0') {
|
||||
printf("defaults write: invalid input - "
|
||||
"empty property list\n");
|
||||
exit(0);
|
||||
}
|
||||
|
||||
/*
|
||||
* Convert read property list from C string format to
|
||||
* an NSString or a structured property list.
|
||||
*/
|
||||
obj = [NSString stringWithCString: start];
|
||||
if (*start == '(' || *start == '{' || *start == '<') {
|
||||
id tmp = [obj propertyList];
|
||||
|
||||
if (tmp == nil) {
|
||||
printf("defaults write: invalid input - "
|
||||
"bad property list\n");
|
||||
exit(0);
|
||||
}
|
||||
else {
|
||||
obj = tmp;
|
||||
}
|
||||
}
|
||||
|
||||
domain = [[defs persistentDomainForName: owner] mutableCopy];
|
||||
if (domain == nil) {
|
||||
domain = [NSMutableDictionary dictionaryWithCapacity:1];
|
||||
}
|
||||
[domain setObject: obj forKey: name];
|
||||
}
|
||||
}
|
||||
else {
|
||||
owner = [args objectAtIndex: i++];
|
||||
if ([args count] <= i) {
|
||||
NSLog(@"defaults: no dictionary or key for write!\n");
|
||||
exit(0);
|
||||
}
|
||||
name = [args objectAtIndex: i++];
|
||||
if ([args count] > i) {
|
||||
const char *ptr;
|
||||
|
||||
value = [args objectAtIndex: i];
|
||||
ptr = [value cString];
|
||||
|
||||
if (*ptr == '(' || *ptr == '{' || *ptr == '<') {
|
||||
obj = [value propertyList];
|
||||
|
||||
if (obj == nil) {
|
||||
printf("defaults write: invalid input - "
|
||||
"bad property list\n");
|
||||
exit(0);
|
||||
}
|
||||
}
|
||||
else {
|
||||
obj = value;
|
||||
}
|
||||
|
||||
domain = [[defs persistentDomainForName: owner] mutableCopy];
|
||||
if (domain == nil) {
|
||||
domain = [NSMutableDictionary dictionaryWithCapacity:1];
|
||||
}
|
||||
[domain setObject: obj forKey: name];
|
||||
}
|
||||
else {
|
||||
domain = [name propertyList];
|
||||
if (domain == nil ||
|
||||
[domain isKindOfClass: [NSDictionary class]] == NO) {
|
||||
NSLog(@"defaults write: domain is not a dictionary!\n");
|
||||
exit(0);
|
||||
}
|
||||
}
|
||||
}
|
||||
[defs setPersistentDomain: domain forName: owner];
|
||||
|
||||
if ([defs synchronize] == NO) {
|
||||
NSLog(@"defaults: unable to write to defaults database - %s\n",
|
||||
strerror(errno));
|
||||
}
|
||||
}
|
||||
else if ([[args objectAtIndex: i] isEqual: @"delete"]) {
|
||||
if ([args count] == ++i) {
|
||||
char buf[BUFSIZ];
|
||||
|
||||
while (fgets(buf, sizeof(buf), stdin) != 0) {
|
||||
char *ptr;
|
||||
char *start;
|
||||
|
||||
start = buf;
|
||||
ptr = start;
|
||||
while (*ptr && !isspace(*ptr)) {
|
||||
ptr++;
|
||||
}
|
||||
if (*ptr) {
|
||||
*ptr++ = '\0';
|
||||
}
|
||||
while (isspace(*ptr)) {
|
||||
ptr++;
|
||||
}
|
||||
if (*start == '\0') {
|
||||
printf("defaults delete: invalid input\n");
|
||||
exit(0);
|
||||
}
|
||||
owner = [NSString stringWithCString: start];
|
||||
start = ptr;
|
||||
ptr = start;
|
||||
while (*ptr && !isspace(*ptr)) {
|
||||
ptr++;
|
||||
}
|
||||
if (*ptr) {
|
||||
*ptr++ = '\0';
|
||||
}
|
||||
while (isspace(*ptr)) {
|
||||
ptr++;
|
||||
}
|
||||
if (*start == '\0') {
|
||||
printf("defaults delete: invalid input\n");
|
||||
exit(0);
|
||||
}
|
||||
name = [NSString stringWithCString: start];
|
||||
domain = [[defs persistentDomainForName: owner] mutableCopy];
|
||||
if (domain == nil || [domain objectForKey: name] == nil) {
|
||||
printf("defaults delete: couldn't remove %s owned by %s\n",
|
||||
[name cString], [owner cString]);
|
||||
}
|
||||
else {
|
||||
[domain removeObjectForKey: name];
|
||||
[defs setPersistentDomain: domain forName: owner];
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
owner = [args objectAtIndex: i++];
|
||||
if ([args count] > i) {
|
||||
name = [args objectAtIndex: i];
|
||||
}
|
||||
else {
|
||||
name = nil;
|
||||
}
|
||||
if (name) {
|
||||
domain = [[defs persistentDomainForName: owner] mutableCopy];
|
||||
if (domain == nil || [domain objectForKey: name] == nil) {
|
||||
printf("dremove: couldn't remove %s owned by %s\n",
|
||||
[name cString], [owner cString]);
|
||||
}
|
||||
else {
|
||||
[domain removeObjectForKey: name];
|
||||
[defs setPersistentDomain: domain forName: owner];
|
||||
}
|
||||
}
|
||||
else {
|
||||
[defs removePersistentDomainForName: owner];
|
||||
}
|
||||
}
|
||||
if ([defs synchronize] == NO) {
|
||||
NSLog(@"defaults: unable to write to defaults database - %s\n",
|
||||
strerror(errno));
|
||||
}
|
||||
}
|
||||
else if ([[args objectAtIndex: i] isEqual: @"domains"]) {
|
||||
domains = [defs persistentDomainNames];
|
||||
for (i = 0; i < [domains count]; i++) {
|
||||
NSString *domainName = [domains objectAtIndex: i];
|
||||
|
||||
printf("%s\n", [domainName cString]);
|
||||
}
|
||||
}
|
||||
else if ([[args objectAtIndex: i] isEqual: @"find"]) {
|
||||
if ([args count] == ++i) {
|
||||
NSLog(@"defaults: no arguments for find!\n");
|
||||
exit(0);
|
||||
}
|
||||
name = [args objectAtIndex: i];
|
||||
|
||||
domains = [defs persistentDomainNames];
|
||||
for (i = 0; i < [domains count]; i++) {
|
||||
NSString *domainName = [domains objectAtIndex: i];
|
||||
NSDictionary *dom;
|
||||
|
||||
if ([domainName isEqual: name]) {
|
||||
printf("%s\n", [domainName cString]);
|
||||
found = YES;
|
||||
}
|
||||
|
||||
dom = [defs persistentDomainForName: domainName];
|
||||
if (dom) {
|
||||
NSEnumerator *enumerator;
|
||||
NSString *key;
|
||||
|
||||
enumerator = [dom keyEnumerator];
|
||||
while ((key = [enumerator nextObject]) != nil) {
|
||||
id obj = [dom objectForKey: key];
|
||||
|
||||
if ([key isEqual: name]) {
|
||||
printf("%s %s\n", [domainName cString], [key cString]);
|
||||
found = YES;
|
||||
}
|
||||
if ([obj isKindOfClass: [NSString class]]) {
|
||||
if ([obj isEqual: name]) {
|
||||
printf("%s %s %s\n",
|
||||
[domainName cString],
|
||||
[key cString],
|
||||
[obj cString]);
|
||||
found = YES;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (found == NO) {
|
||||
printf("defaults find: couldn't find value\n");
|
||||
}
|
||||
}
|
||||
else {
|
||||
NSLog(@"defaults: unknown option supplied!\n");
|
||||
exit(0);
|
||||
}
|
||||
|
||||
exit(0);
|
||||
}
|
||||
|
||||
|
190
Tools/dread.m
190
Tools/dread.m
|
@ -35,8 +35,10 @@ main(int argc, char** argv)
|
|||
NSProcessInfo *proc;
|
||||
NSArray *args;
|
||||
NSArray *domains;
|
||||
NSString *owner;
|
||||
NSString *name;
|
||||
NSString *owner = nil;
|
||||
NSString *name = nil;
|
||||
NSString *user = nil;
|
||||
BOOL found = NO;
|
||||
int i;
|
||||
|
||||
[NSObject enableDoubleReleaseCheck: YES];
|
||||
|
@ -47,44 +49,119 @@ main(int argc, char** argv)
|
|||
exit(0);
|
||||
}
|
||||
|
||||
defs = [NSUserDefaults standardUserDefaults];
|
||||
args = [proc arguments];
|
||||
|
||||
for (i = 0; i < [args count]; i++) {
|
||||
if ([[args objectAtIndex: i] isEqual: @"--help"]) {
|
||||
printf(
|
||||
"\nThe 'dread' command lets you to read a user's defaults database.\n"
|
||||
"WARNING - this program is obsolete - please use 'defaults read' instead.\n\n"
|
||||
"Results are printed on standard output in a format suitable for input to\n"
|
||||
"the 'dwrite' command. The value of each default is quoted with \"'\" and\n"
|
||||
"may wrap over line boundaries.\n"
|
||||
"Single quotes used within a default value are repeated.\n\n"
|
||||
"If you have read access to another user's defaults database, you may include\n"
|
||||
"the '-u' flag to read that user's database rather than your own.\n\n");
|
||||
printf(
|
||||
"dread [-u uname] -g key\n"
|
||||
" read the named default from the global domain.\n\n");
|
||||
printf(
|
||||
"dread [-u uname] -l\n"
|
||||
" read all defaults from all domains.\n\n");
|
||||
printf(
|
||||
"dread [-u uname] -n key\n"
|
||||
" read values named 'key' from all domains.\n\n");
|
||||
printf(
|
||||
"dread [-u uname] -o domain\n"
|
||||
" read all defaults from the specified domain.\n\n");
|
||||
printf(
|
||||
"dread [-u uname] domain key\n"
|
||||
" read default with name 'key' from domain 'domain'.\n\n");
|
||||
printf(
|
||||
"dread [-u uname] key\n"
|
||||
" read default named 'key' from the global domain.\n");
|
||||
exit(0);
|
||||
}
|
||||
}
|
||||
|
||||
i = 0;
|
||||
if ([args count] <= i) {
|
||||
NSLog(@"too few arguments supplied!\n");
|
||||
exit(0);
|
||||
}
|
||||
|
||||
if ([[args objectAtIndex: i] isEqual: @"-u"]) {
|
||||
if ([args count] > ++i) {
|
||||
user = [args objectAtIndex: i++];
|
||||
}
|
||||
else {
|
||||
NSLog(@"no name supplied for -u option!\n");
|
||||
exit(0);
|
||||
}
|
||||
}
|
||||
|
||||
if ([args count] <= i) {
|
||||
NSLog(@"too few arguments supplied!\n");
|
||||
exit(0);
|
||||
}
|
||||
|
||||
if ([[args objectAtIndex: i] isEqual: @"-g"]) {
|
||||
owner = NSGlobalDomain;
|
||||
if ([args count] > ++i) {
|
||||
name = [args objectAtIndex: i];
|
||||
}
|
||||
else {
|
||||
NSLog(@"no key supplied for -g option!\n");
|
||||
exit(0);
|
||||
}
|
||||
}
|
||||
else if ([[args objectAtIndex: i] isEqual: @"-n"]) {
|
||||
owner = nil;
|
||||
if ([args count] > ++i) {
|
||||
name = [args objectAtIndex: i];
|
||||
}
|
||||
else {
|
||||
NSLog(@"no key supplied for -n option!\n");
|
||||
exit(0);
|
||||
}
|
||||
}
|
||||
else if ([[args objectAtIndex: i] isEqual: @"-o"]) {
|
||||
name = nil;
|
||||
if ([args count] > ++i) {
|
||||
owner = [args objectAtIndex: i];
|
||||
}
|
||||
else {
|
||||
NSLog(@"no domain name supplied for -o option!\n");
|
||||
exit(0);
|
||||
}
|
||||
}
|
||||
else if ([[args objectAtIndex: i] isEqual: @"-l"]) {
|
||||
owner = nil;
|
||||
name = nil;
|
||||
}
|
||||
else {
|
||||
if ([args count] > i+1) {
|
||||
owner = [args objectAtIndex: i];
|
||||
name = [args objectAtIndex: ++i];
|
||||
}
|
||||
else {
|
||||
owner = NSGlobalDomain;
|
||||
name = [args objectAtIndex: i];
|
||||
}
|
||||
}
|
||||
|
||||
if (user) {
|
||||
defs = [[NSUserDefaults alloc] initWithUser: user];
|
||||
}
|
||||
else {
|
||||
defs = [NSUserDefaults standardUserDefaults];
|
||||
}
|
||||
if (defs == nil) {
|
||||
NSLog(@"unable to access defaults database!\n");
|
||||
exit(0);
|
||||
}
|
||||
|
||||
args = [proc arguments];
|
||||
if ([args count] == 0) {
|
||||
NSLog(@"no arguments supplied!\n");
|
||||
exit(0);
|
||||
}
|
||||
|
||||
if ([[args objectAtIndex: 0] isEqual: @"-g"]) {
|
||||
owner = NSGlobalDomain;
|
||||
name = [args objectAtIndex: 1];
|
||||
}
|
||||
else if ([[args objectAtIndex: 0] isEqual: @"-l"]) {
|
||||
owner = nil;
|
||||
name = nil;
|
||||
}
|
||||
else if ([[args objectAtIndex: 0] isEqual: @"-n"]) {
|
||||
owner = NSGlobalDomain;
|
||||
name = [args objectAtIndex: 1];
|
||||
}
|
||||
else if ([[args objectAtIndex: 0] isEqual: @"-o"]) {
|
||||
owner = [args objectAtIndex: 1];
|
||||
name = nil;
|
||||
}
|
||||
else {
|
||||
if ([args count] > 1) {
|
||||
owner = [args objectAtIndex: 0];
|
||||
name = [args objectAtIndex: 1];
|
||||
}
|
||||
else {
|
||||
owner = NSGlobalDomain;
|
||||
name = [args objectAtIndex: 0];
|
||||
}
|
||||
}
|
||||
/* We don't want dwrite in the defaults database - so remove it. */
|
||||
[defs removePersistentDomainForName: [proc processName]];
|
||||
|
||||
domains = [defs persistentDomainNames];
|
||||
for (i = 0; i < [domains count]; i++) {
|
||||
|
@ -101,29 +178,48 @@ main(int argc, char** argv)
|
|||
|
||||
enumerator = [dom keyEnumerator];
|
||||
while ((key = [enumerator nextObject]) != nil) {
|
||||
id obj = [dom objectForKey: key];
|
||||
id obj = [dom objectForKey: key];
|
||||
const char *ptr;
|
||||
|
||||
printf("%s %s %s\n",
|
||||
[domainName cString], [key cString],
|
||||
[[obj description] cString]);
|
||||
printf("%s %s '", [domainName cString], [key cString]);
|
||||
ptr = [[obj description] cString];
|
||||
while (*ptr) {
|
||||
if (*ptr == '\'') {
|
||||
putchar('\'');
|
||||
}
|
||||
putchar(*ptr);
|
||||
ptr++;
|
||||
}
|
||||
printf("'\n");
|
||||
}
|
||||
}
|
||||
else {
|
||||
id obj = [dom objectForKey: name];
|
||||
id obj = [dom objectForKey: name];
|
||||
|
||||
if (obj) {
|
||||
printf("%s %s %s\n",
|
||||
[domainName cString], [name cString],
|
||||
[[obj description] cString]);
|
||||
}
|
||||
else {
|
||||
printf("dread: couldn't read default\n");
|
||||
const char *ptr;
|
||||
|
||||
printf("%s %s '", [domainName cString], [name cString]);
|
||||
ptr = [[obj description] cString];
|
||||
while (*ptr) {
|
||||
if (*ptr == '\'') {
|
||||
putchar('\'');
|
||||
}
|
||||
putchar(*ptr);
|
||||
ptr++;
|
||||
}
|
||||
printf("'\n");
|
||||
found = YES;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (found == NO && name != nil) {
|
||||
printf("dread: couldn't read default\n");
|
||||
}
|
||||
|
||||
exit(0);
|
||||
}
|
||||
|
||||
|
|
125
Tools/dremove.m
125
Tools/dremove.m
|
@ -38,6 +38,8 @@ main(int argc, char** argv)
|
|||
NSMutableDictionary *domain;
|
||||
NSString *owner;
|
||||
NSString *name;
|
||||
NSString *user = nil;
|
||||
int i;
|
||||
|
||||
[NSObject enableDoubleReleaseCheck: YES];
|
||||
|
||||
|
@ -47,14 +49,57 @@ main(int argc, char** argv)
|
|||
exit(0);
|
||||
}
|
||||
|
||||
defs = [NSUserDefaults standardUserDefaults];
|
||||
args = [proc arguments];
|
||||
|
||||
for (i = 0; i < [args count]; i++) {
|
||||
if ([[args objectAtIndex: i] isEqual: @"--help"]) {
|
||||
printf(
|
||||
"The 'dremove' command lets you delete entries in a user's defaults database.\n"
|
||||
"WARNING - this program is obsolete - please use 'defaults delete' instead.\n\n"
|
||||
"The value written must be a property list and must be enclosed in quotes.\n"
|
||||
"If you have write access to another user's database, you may include\n"
|
||||
"the '-u' flag to modify that user's database rather than your own.\n\n");
|
||||
printf(
|
||||
"dremove [-u uname] -g key\n"
|
||||
" removed the named default to the global domain.\n\n");
|
||||
printf(
|
||||
"dremove [-u uname] -o domain\n"
|
||||
" removed the named domain and all its contents.\n\n");
|
||||
printf(
|
||||
"dremove [-u uname] domain key\n"
|
||||
" remove default with name 'key' from domain 'domain'.\n\n");
|
||||
printf(
|
||||
"dremove\n"
|
||||
" read the standard input for a series of lines listing domain name and\n"
|
||||
" default key pairs to be removed. Domain names and default keys must be\n"
|
||||
" separated by spaces.\n");
|
||||
exit(0);
|
||||
}
|
||||
}
|
||||
|
||||
i = 0;
|
||||
if ([args count] > i && [[args objectAtIndex: i] isEqual: @"-u"]) {
|
||||
if ([args count] > ++i) {
|
||||
user = [args objectAtIndex: i++];
|
||||
}
|
||||
else {
|
||||
NSLog(@"no name supplied for -u option!\n");
|
||||
exit(0);
|
||||
}
|
||||
}
|
||||
|
||||
if (user) {
|
||||
defs = [[NSUserDefaults alloc] initWithUser: user];
|
||||
}
|
||||
else {
|
||||
defs = [NSUserDefaults standardUserDefaults];
|
||||
}
|
||||
if (defs == nil) {
|
||||
NSLog(@"unable to access defaults database!\n");
|
||||
exit(0);
|
||||
}
|
||||
|
||||
args = [proc arguments];
|
||||
if ([args count] == 0) {
|
||||
if ([args count] == i) {
|
||||
char buf[BUFSIZ*10];
|
||||
|
||||
while (fgets(buf, sizeof(buf), stdin) != 0) {
|
||||
|
@ -63,21 +108,9 @@ main(int argc, char** argv)
|
|||
|
||||
start = buf;
|
||||
|
||||
if (*start == '"') {
|
||||
for (ptr = ++start; *ptr; ptr++) {
|
||||
if (*ptr == '\\' && ptr[1] != '\0') {
|
||||
ptr++;
|
||||
}
|
||||
else if (*ptr == '"') {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
ptr = start;
|
||||
while (*ptr && !isspace(*ptr)) {
|
||||
ptr++;
|
||||
}
|
||||
ptr = start;
|
||||
while (*ptr && !isspace(*ptr)) {
|
||||
ptr++;
|
||||
}
|
||||
if (*ptr) {
|
||||
*ptr++ = '\0';
|
||||
|
@ -92,21 +125,9 @@ main(int argc, char** argv)
|
|||
owner = [NSString stringWithCString: start];
|
||||
start = ptr;
|
||||
|
||||
if (*start == '"') {
|
||||
for (ptr = ++start; *ptr; ptr++) {
|
||||
if (*ptr == '\\' && ptr[1] != '\0') {
|
||||
ptr++;
|
||||
}
|
||||
else if (*ptr == '"') {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
ptr = start;
|
||||
while (*ptr && !isspace(*ptr)) {
|
||||
ptr++;
|
||||
}
|
||||
ptr = start;
|
||||
while (*ptr && !isspace(*ptr)) {
|
||||
ptr++;
|
||||
}
|
||||
if (*ptr) {
|
||||
*ptr++ = '\0';
|
||||
|
@ -121,8 +142,8 @@ main(int argc, char** argv)
|
|||
name = [NSString stringWithCString: start];
|
||||
domain = [[defs persistentDomainForName: owner] mutableCopy];
|
||||
if (domain == nil || [domain objectForKey: name] == nil) {
|
||||
printf("dremoveL couldn't remove %s owned by %s\n",
|
||||
[name quotedCString], [owner quotedCString]);
|
||||
printf("dremove: couldn't remove %s owned by %s\n",
|
||||
[name cString], [owner cString]);
|
||||
}
|
||||
else {
|
||||
[domain removeObjectForKey: name];
|
||||
|
@ -130,27 +151,43 @@ main(int argc, char** argv)
|
|||
}
|
||||
}
|
||||
}
|
||||
else if ([[args objectAtIndex: 0] isEqual: @"-g"]) {
|
||||
else if ([[args objectAtIndex: i] isEqual: @"-g"]) {
|
||||
owner = NSGlobalDomain;
|
||||
name = [args objectAtIndex: 1];
|
||||
if ([args count] > ++i) {
|
||||
name = [args objectAtIndex: i];
|
||||
}
|
||||
else {
|
||||
NSLog(@"no key supplied for -g option.\n");
|
||||
exit(0);
|
||||
}
|
||||
domain = [[defs persistentDomainForName: owner] mutableCopy];
|
||||
if (domain == nil || [domain objectForKey: name] == nil) {
|
||||
printf("dremoveL couldn't remove %s owned by %s\n",
|
||||
[name quotedCString], [owner quotedCString]);
|
||||
printf("dremove: couldn't remove %s owned by %s\n",
|
||||
[name cString], [owner cString]);
|
||||
}
|
||||
else {
|
||||
[domain removeObjectForKey: name];
|
||||
[defs setPersistentDomain: domain forName: owner];
|
||||
}
|
||||
}
|
||||
else if ([[args objectAtIndex: i] isEqual: @"-o"]) {
|
||||
if ([args count] > ++i) {
|
||||
owner = [args objectAtIndex: i];
|
||||
}
|
||||
else {
|
||||
NSLog(@"no domain supplied for -o option.\n");
|
||||
exit(0);
|
||||
}
|
||||
[defs removePersistentDomainForName: owner];
|
||||
}
|
||||
else {
|
||||
if ([args count] > 1) {
|
||||
owner = [args objectAtIndex: 0];
|
||||
name = [args objectAtIndex: 1];
|
||||
if ([args count] > i+1) {
|
||||
owner = [args objectAtIndex: i];
|
||||
name = [args objectAtIndex: ++i];
|
||||
domain = [[defs persistentDomainForName: owner] mutableCopy];
|
||||
if (domain == nil || [domain objectForKey: name] == nil) {
|
||||
printf("dremoveL couldn't remove %s owned by %s\n",
|
||||
[name quotedCString], [owner quotedCString]);
|
||||
printf("dremove: couldn't remove %s owned by %s\n",
|
||||
[name cString], [owner cString]);
|
||||
}
|
||||
else {
|
||||
[domain removeObjectForKey: name];
|
||||
|
|
207
Tools/dwrite.m
207
Tools/dwrite.m
|
@ -38,7 +38,9 @@ main(int argc, char** argv)
|
|||
NSString *owner;
|
||||
NSString *name;
|
||||
NSString *value;
|
||||
NSString *user = nil;
|
||||
const char *text;
|
||||
const char *str;
|
||||
id obj = nil;
|
||||
int i;
|
||||
|
||||
|
@ -50,14 +52,60 @@ main(int argc, char** argv)
|
|||
exit(0);
|
||||
}
|
||||
|
||||
defs = [NSUserDefaults standardUserDefaults];
|
||||
args = [proc arguments];
|
||||
|
||||
for (i = 0; i < [args count]; i++) {
|
||||
if ([[args objectAtIndex: i] isEqual: @"--help"]) {
|
||||
printf(
|
||||
"The 'dwrite' command lets you modify a user's defaults database.\n"
|
||||
"WARNING - this program is obsolete - please use 'defaults write' instead.\n\n"
|
||||
"The value written must be a property list and (if being read from standard\n"
|
||||
"input) must be enclosed in single quotes unless it is a simple alphanumeric\n"
|
||||
"string.\n"
|
||||
"Quotes appearing inside a quoted property list must be repeated to avoid\n"
|
||||
"their being interpreted as the end of the property list.\n"
|
||||
"If you have write access to another user's database, you may include\n"
|
||||
"the '-u' flag to modify that user's database rather than your own.\n\n");
|
||||
printf(
|
||||
"dwrite [-u uname] -g key value\n"
|
||||
" write the named default to the global domain.\n\n");
|
||||
printf(
|
||||
"dwrite [-u uname] domain key value\n"
|
||||
" write default with name 'key' to domain 'domain'.\n\n");
|
||||
printf(
|
||||
"dwrite\n"
|
||||
" read the standard input for a series of lines listing defaults to be\n"
|
||||
" written. Domain names, default keys, and default values must be\n"
|
||||
" separated on each line by spaces.\n");
|
||||
exit(0);
|
||||
}
|
||||
}
|
||||
|
||||
i = 0;
|
||||
if ([args count] > i && [[args objectAtIndex: i] isEqual: @"-u"]) {
|
||||
if ([args count] > ++i) {
|
||||
user = [args objectAtIndex: i++];
|
||||
}
|
||||
else {
|
||||
NSLog(@"no name supplied for -u option!\n");
|
||||
exit(0);
|
||||
}
|
||||
}
|
||||
|
||||
if (user) {
|
||||
defs = [[NSUserDefaults alloc] initWithUser: user];
|
||||
}
|
||||
else {
|
||||
defs = [NSUserDefaults standardUserDefaults];
|
||||
}
|
||||
if (defs == nil) {
|
||||
NSLog(@"unable to access defaults database!\n");
|
||||
exit(0);
|
||||
}
|
||||
/* We don't want dwrite in the defaults database - so remove it. */
|
||||
[defs removePersistentDomainForName: [proc processName]];
|
||||
|
||||
args = [proc arguments];
|
||||
if ([args count] == 0) {
|
||||
if ([args count] == i) {
|
||||
char buf[BUFSIZ*10];
|
||||
|
||||
while (fgets(buf, sizeof(buf), stdin) != 0) {
|
||||
|
@ -67,21 +115,9 @@ main(int argc, char** argv)
|
|||
obj = nil;
|
||||
start = buf;
|
||||
|
||||
if (*start == '"') {
|
||||
for (ptr = ++start; *ptr; ptr++) {
|
||||
if (*ptr == '\\' && ptr[1] != '\0') {
|
||||
ptr++;
|
||||
}
|
||||
else if (*ptr == '"') {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
ptr = start;
|
||||
while (*ptr && !isspace(*ptr)) {
|
||||
ptr++;
|
||||
}
|
||||
ptr = start;
|
||||
while (*ptr && !isspace(*ptr)) {
|
||||
ptr++;
|
||||
}
|
||||
if (*ptr) {
|
||||
*ptr++ = '\0';
|
||||
|
@ -90,27 +126,21 @@ main(int argc, char** argv)
|
|||
ptr++;
|
||||
}
|
||||
if (*start == '\0') {
|
||||
printf("dwrite: invalid input\n");
|
||||
printf("dwrite: invalid input - nul domain name\n");
|
||||
exit(0);
|
||||
}
|
||||
for (str = start; *str; str++) {
|
||||
if (isspace(*str)) {
|
||||
printf("dwrite: invalid input - space in domain name.\n");
|
||||
exit(0);
|
||||
}
|
||||
}
|
||||
owner = [NSString stringWithCString: start];
|
||||
start = ptr;
|
||||
|
||||
if (*start == '"') {
|
||||
for (ptr = ++start; *ptr; ptr++) {
|
||||
if (*ptr == '\\' && ptr[1] != '\0') {
|
||||
ptr++;
|
||||
}
|
||||
else if (*ptr == '"') {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
ptr = start;
|
||||
while (*ptr && !isspace(*ptr)) {
|
||||
ptr++;
|
||||
}
|
||||
ptr = start;
|
||||
while (*ptr && !isspace(*ptr)) {
|
||||
ptr++;
|
||||
}
|
||||
if (*ptr) {
|
||||
*ptr++ = '\0';
|
||||
|
@ -119,41 +149,33 @@ main(int argc, char** argv)
|
|||
ptr++;
|
||||
}
|
||||
if (*start == '\0') {
|
||||
printf("dwrite: invalid input\n");
|
||||
printf("dwrite: invalid input - nul default name.\n");
|
||||
exit(0);
|
||||
}
|
||||
for (str = start; *str; str++) {
|
||||
if (isspace(*str)) {
|
||||
printf("dwrite: invalid input - space in default name.\n");
|
||||
exit(0);
|
||||
}
|
||||
}
|
||||
name = [NSString stringWithCString: start];
|
||||
start = ptr;
|
||||
|
||||
if (*start == '(' || *start == '{' || *start == '<') {
|
||||
ptr = &start[strlen(start)-1];
|
||||
while (isspace(*ptr)) {
|
||||
*ptr-- = '\0';
|
||||
}
|
||||
value = [NSString stringWithCString: start];
|
||||
while ((obj = [value propertyList]) == nil) {
|
||||
if (fgets(buf, sizeof(buf), stdin) != 0) {
|
||||
ptr = &buf[strlen(buf)-1];
|
||||
while (isspace(*ptr)) {
|
||||
*ptr-- = '\0';
|
||||
if (*start == '\'') {
|
||||
for (ptr = ++start; ; ptr++) {
|
||||
if (*ptr == '\0') {
|
||||
if (fgets(ptr, sizeof(buf) - (ptr-buf), stdin) == 0) {
|
||||
printf("dwrite: invalid input - no final quote.\n");
|
||||
exit(0);
|
||||
}
|
||||
value = [value stringByAppendingString: @"\n"];
|
||||
value = [value stringByAppendingString:
|
||||
[NSString stringWithCString: buf]];
|
||||
}
|
||||
else {
|
||||
printf("dwrite: invalid input\n");
|
||||
exit(0);
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (*start == '"') {
|
||||
for (ptr = ++start; *ptr; ptr++) {
|
||||
if (*ptr == '\\' && ptr[1] != '\0') {
|
||||
ptr++;
|
||||
}
|
||||
else if (*ptr == '"') {
|
||||
break;
|
||||
if (*ptr == '\'') {
|
||||
if (ptr[1] == '\'') {
|
||||
strcpy(ptr, &ptr[1]);
|
||||
}
|
||||
else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -168,10 +190,21 @@ main(int argc, char** argv)
|
|||
*ptr++ = '\0';
|
||||
}
|
||||
if (*start == '\0') {
|
||||
printf("dwrite: invalid input\n");
|
||||
printf("dwrite: invalid input - empty property list\n");
|
||||
exit(0);
|
||||
}
|
||||
obj = [NSString stringWithCString: start];
|
||||
if (*start == '(' || *start == '{' || *start == '<') {
|
||||
id tmp = [obj propertyList];
|
||||
|
||||
if (tmp == nil) {
|
||||
printf("dwrite: invalid input - bad property list\n");
|
||||
exit(0);
|
||||
}
|
||||
else {
|
||||
obj = tmp;
|
||||
}
|
||||
}
|
||||
}
|
||||
domain = [[defs persistentDomainForName: owner] mutableCopy];
|
||||
if (domain == nil) {
|
||||
|
@ -181,18 +214,28 @@ main(int argc, char** argv)
|
|||
[defs setPersistentDomain: domain forName: owner];
|
||||
}
|
||||
}
|
||||
else if ([[args objectAtIndex: 0] isEqual: @"-g"]) {
|
||||
if ([args count] > 2) {
|
||||
else if ([[args objectAtIndex: i] isEqual: @"-g"]) {
|
||||
if ([args count] > i+2) {
|
||||
owner = NSGlobalDomain;
|
||||
name = [args objectAtIndex: 1];
|
||||
value = [args objectAtIndex: 2];
|
||||
name = [args objectAtIndex: ++i];
|
||||
for (str = [name cString]; *str; str++) {
|
||||
if (isspace(*str)) {
|
||||
printf("dwrite: invalid input - space in default name.\n");
|
||||
exit(0);
|
||||
}
|
||||
}
|
||||
value = [args objectAtIndex: ++i];
|
||||
text = [value cStringNoCopy];
|
||||
if (*text == '(' || *text == '{' || *text == '<') {
|
||||
obj = [value propertyList];
|
||||
}
|
||||
if (obj == nil) {
|
||||
else {
|
||||
obj = value;
|
||||
}
|
||||
if (obj == nil) {
|
||||
printf("dwrite: invalid input - bad property list\n");
|
||||
exit(0);
|
||||
}
|
||||
domain = [[defs persistentDomainForName: owner] mutableCopy];
|
||||
if (domain == nil) {
|
||||
domain = [NSMutableDictionary dictionaryWithCapacity:1];
|
||||
|
@ -206,17 +249,33 @@ main(int argc, char** argv)
|
|||
}
|
||||
}
|
||||
else {
|
||||
if ([args count] > 2) {
|
||||
owner = [args objectAtIndex: 0];
|
||||
name = [args objectAtIndex: 1];
|
||||
value = [args objectAtIndex: 2];
|
||||
if ([args count] > i+2) {
|
||||
owner = [args objectAtIndex: i];
|
||||
for (str = [owner cString]; *str; str++) {
|
||||
if (isspace(*str)) {
|
||||
printf("dwrite: invalid input - space in domain name.\n");
|
||||
exit(0);
|
||||
}
|
||||
}
|
||||
name = [args objectAtIndex: ++i];
|
||||
for (str = [name cString]; *str; str++) {
|
||||
if (isspace(*str)) {
|
||||
printf("dwrite: invalid input - space in default name.\n");
|
||||
exit(0);
|
||||
}
|
||||
}
|
||||
value = [args objectAtIndex: ++i];
|
||||
text = [value cStringNoCopy];
|
||||
if (*text == '(' || *text == '{' || *text == '<') {
|
||||
obj = [value propertyList];
|
||||
}
|
||||
if (obj == nil) {
|
||||
else {
|
||||
obj = value;
|
||||
}
|
||||
if (obj == nil) {
|
||||
printf("dwrite: invalid input - bad property list\n");
|
||||
exit(0);
|
||||
}
|
||||
domain = [[defs persistentDomainForName: owner] mutableCopy];
|
||||
if (domain == nil) {
|
||||
domain = [NSMutableDictionary dictionaryWithCapacity:1];
|
||||
|
@ -230,8 +289,6 @@ main(int argc, char** argv)
|
|||
}
|
||||
}
|
||||
|
||||
/* We don't want dwrite in the defaults database - so remove it. */
|
||||
[defs removePersistentDomainForName: [proc processName]];
|
||||
[defs synchronize];
|
||||
|
||||
exit(0);
|
||||
|
|
Loading…
Reference in a new issue