diff --git a/ANNOUNCE b/ANNOUNCE index fc83e29ed..4954664b5 100644 --- a/ANNOUNCE +++ b/ANNOUNCE @@ -1,11 +1,7 @@ 1 Announcement ************** - ftp.gnustep.org - - pub/daily-snapshots - -The GNUstep Base Library, version 1.13.1, is now available. +The GNUstep Base Library, version 1.14.0, is now available. 1.1 What is the GNUstep Base Library? ===================================== @@ -22,23 +18,18 @@ portion of the OpenStep standard (the Foundation library). There is more information available at the GNUstep homepage at `http://www.gnustep.org'. - ftp.gnustep.org - - pub/daily-snapshots - -1.2 Noteworthy changes in version `1.13.1' +1.2 Noteworthy changes in version `1.14.0' ========================================== -Various minor bugs and MacOS-X incompatibilities fixed. One important -fix for a possible buffer overrun attack when initialising NSDate -objects from strings. One fix for a serious (crash) bug when -initialising the bundles system in an application which has a lot of -frameworks linked to it. See the release notes for more details. +Many portability (particularly for ms-windows) and MacOS-X +compatibility fixes. New MacOS-X classes and incorporation of +NSAffineTransform and NSSpellServer which were formerly in the gui +library. Improved performance of amssively multithreaded programs. 1.3 Where can you get it? How can you compile it? ================================================== -The gnustep-base-1.13.1.tar.gz distribution file has been placed at +The gnustep-base-1.14.0.tar.gz distribution file has been placed at `ftp://ftp.gnustep.org/pub/gnustep/core'. Please log bug reports on the GNUstep project page diff --git a/ChangeLog b/ChangeLog index 63425e8a9..4cd7ab629 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,127 +1,1664 @@ +2007-04-12 Adam Fedor + + * Version 1.14.0 + +2007-04-11 Richard Frith-Macdonald + + * Documentation/news.texi: + * Documentation/ReleaseNotes.gsdoc: + * Documentation/manual/Compliance.texi: + Add new stable release information and fixx a couple of documentation + errors. + +2007-04-11 Richard Frith-Macdonald + + * Source/Additions/GSXML.m: + * Source/Additions/GSCompatibility.m: + * Source/Additions/GSMime.m: + * Headers/Foundation/NSString.h: + * Headers/Additions/GNUstepBase/GSCategories.h: + * Headers/Additions/GNUstepBase/Unicode.h: + More macos-x portability fixups. + +2007-04-01 Richard Frith-Macdonald + + * Source/GSLocale.m: + * Source/Additions/Unicode.m: + * Headers/Foundation/NSString.h: + * Headers/Additions/GNUstepBase/Unicode.h: + Header/include fixups for macosx portability. + +2007-03-30 Richard Frith-Macdonald + + * Source/NSPredicate.m: ([-parseOr]) Use orPredicateWithSubpredicates + rather than andPredicateWithSubpredicates. Fix for bug #19446. + * Source/unix/NSStream.m: Fix memory leak. + * Source/NSPathUtilities.m: NSSearchPathForDirectoriesInDomains() + Don't include empty paths. + +2007-03-25 Richard Frith-Macdonald + + * Source/NSTimer.m: minor optimisation ... avoid unnecessary use of + autorelease by doing explicit release instead. + +2007-03-22 Richard Frith-Macdonald + + * Source/NSPathUtilities.m: NSTemporaryDirectory() don't raise + exception on error, just log a warning and return nil. + * Source/NSDateFormatter.m: When given an empty string to convert to + a date, just skip the conversion. + +2007-03-21 Nicola Pero + + * Source/NSBundle.m ([+initialize]): Removed unused check. + +2007-03-20 Nicola Pero + + * Source/NSUserDefaults.m ([+standardUserDefaults]): Fixed bug + were the same enumerator variable was reused in the two nested + loops and language resources wouldn't be found. Optimized a + little by factoring some variables out of the inner loop. + Reorganized usage of information from the C locale so that we use + it whenever a language resource lookup can not be found and the C + locale information is precisely for that language, but not + otherwise. + +2007-03-19 Nicola Pero + + * Tools/gsdoc.gsdoc: Removed reference to GNUSTEP_SYSTEM_ROOT; use + up-to-date variables such as GNUSTEP_SYSTEM_LIBRARY and + GNUSTEP_SYSTEM_DOC. + * Tools/gsdoc-1_0_1.rnc: Same change. + * Tools/gsdoc.7: Same change. + * Tools/gdomap.8: Same change. + + * INSTALL: Updated. + +2007-03-19 Richard Frith-Macdonald + + * Source/NSDictionary.m: Correct errors in documentation about keys + being retained when they are in fact copied. + 2007-03-17 Adam Fedor * config/config.trampoline.c: Check for proper CPU macro for Darwin * configure.ac: Don't enable libffi by default on Darwin (patches from Wolfgang Lux). +2007-03-17 Nicola Pero + + * SSL/GNUmakefile: Install the SSL bundle in the versioned + gnustep-base resource directory. + * Source/NSFileHandle.m ([+sslClass]): Load the SSL bundle from + the versioned gnustep-base resource directory. + +2007-03-17 Nicola Pero + + * Source/Makefile.postamble (before-uninstall): Remove GSConfig.h. + +2007-03-17 Nicola Pero + + * Source/NSBundle.m ([+bundleForLibrary:version:]): Fixed looking + up library resource bundle when no version is provided. + +2007-03-16 Richard Frith-Macdonald + + * Source/unix/NSStream.m: + * Source/win32/NSStreamWin32.m: + Try to ensure that end of stream events are sent reliably. + +2007-03-15 Richard Frith-Macdonald + + * Source/NSPropertyList.m: ([GSBinaryPLParser-readCountAt:]) + Handle counts for objects larger than 64KB correctly. + +2007-03-14 Richard Frith-Macdonald + + * configure.ac: By default disable the GNUSTEP_CONFIOG_FILE + environment variable on windows so that we don't accidentally + use the development config file (with unix style paths) when + we want to be using runtime config (with windows paths). + * configure: Regenerate + * Source/GSPrivate.h: New private function to determine native + C-string encoding. + * Source/Additions/Unicode.m: ditto + * Source/GSLocale.m: Use native C-String encoding to handle locale + information strings. + +2007-03-14 Nicola Pero + + * Source/NSUserDefaults.m ([+standardUserDefaults]): Manually + lookup gnustep-base language resources without using NSBundle to + break the bootstrap chicken-and-egg problem between NSBundle and + NSUserDefaults. + +2007-03-14 Richard Frith-Macdonald + + * Source/Additions/GSXML.m: Fix memory leak caused by url handle + retaining xmlrpc object as a client. + +2007-03-13 Richard Frith-Macdonald + + * Source/GSLocale.m: Expect locale information (nl_langinfo) to be in + default c-string encoding ... though it's debatable how one knows what + that should be. + +2007-03-12 Richard Frith-Macdonald + + * NSTimeZones/NSTimeZones.tar: regenerated. + * Source/GSString.m: getCString_c() Fix error freeing unallocated + memory when converting a zero length constant string to external + cstring representation. + +2007-03-09 Nicola Pero + + Implemented library resource bundle versioning. Updated + gnustep-base to use versioned resources. + * Source/NSBundle ([+bundleForLibrary:version]): New method. + Allow to request the resource bundle for a specific version. + Changed bundle resource location to be + GNUSTEP_LIBRARY/Libraries//Versions//Resources + to allow versioned resources and be similar to framework resources + - will be handy in the future. Fall back to the old unversioned + bundle at GNUSTEP_LIBRARY/Libraries/Resources/ if no + specific version is required and no versioned bundle can be found. + ([+bundleForLibrary:]): Implemented in terms of + +bundleForLibrary:version:. Should be backwards compatible if + you're not using resource versioning yet. + ([+initialize]): When creating _gnustep_bundle, use + [+bundleForLibrary:version:] to get the appropriate version of the + bundle. + + * Headers/Foundation/NSBundle.h ([+bundleForLibrary:version:]): + New method; updated documentation for this method and for + [+bundleForLibrary:]. + + * Resources/GNUmakefile: Include ../Version and install into the + new versioned directory. + * NSTimeZones/GNUmakefile: Same changes. + * Source/GNUmakefile: Same changes. + + * Source/NSBundle.m ([+bundleForClass:]): If we are asked for the + bundle for NSObject, return _gnustep_bundle (prepared during + +initialize) immediately. + * Source/NSTimeZone.m (_time_zone_path): Use bundleForClass: + NSObject to get the gnustep-base bundle immediately and safely. + * Source/NSUserDefaults.m ([+standardUserDefaults]): Same change. + + * Source/GNUmakefile (libgnustep-base_INTERFACE_VERSION, + libgnustep-baseadd_INTERFACE_VERSION): Use more standard makefile + syntax. + +2007-03-09 Richard Frith-Macdonald + + * Source/NSProcessInfo.m: On mswindows, don't count a '.exe' + extension as part of the process name. + * Source/NSUserDefaults.m: Revert last change ... now done in + NSProcessInfo.m + +2007-03-08 Richard Frith-Macdonald + + * Source/Addictions/GSXML.m: Cope with cancellation of load from URL + in XMLRPC better. + +2007-03-08 Nicola Pero + + * Source/NSPathUtilities.h (GSAdminToolsDirectory): New directory + key. + * Source/NSPathUtilities.m: Implemented it. + +2007-03-07 Richard Frith-Macdonald + + * Source/GSHTTPURLHandle.m: Mimic MacOS-X behavior and cancel loading + if http status code is not in the 200-299 (success) range. + +2007-03-07 Richard Frith-Macdonald + + * Tools/objctidy.m: Removed ... should not have been added really as + it's very unreliable ... better remove before it accidentally gets + into a stable release. + +2007-03-06 Richard Frith-Macdonald + + * Source/NSSpellServer.m: Use Library directory in user domain for + local dictionaries. + * Source/NSDistributedNotificationCenter.m: autolaunch gdnc with the + --auto option. + * Tools/gdnc.m: Understand --auto to mean that we should shut down + automatically when all connections in to us are dropped. + +2007-03-06 Nicola Pero + + * configure.ac: Added GNUSTEP_SYSTEM_USERS_DIR, + GNUSTEP_NETWORK_USERS_DIR and GNUSTEP_LOCAL_USERS_DIR. + * configure: Regenerated. + * Headers/Additions/GNUstepBase/config.h.in: Regenerated. + * Source/NSPathUtilities.m: Read and process the new variables; + fixed NSUserDirectory to return the proper GNUSTEP_*_USERS_DIR + instead of the user's home directory. + +2007-03-06 Richard Frith-Macdonald + + * Source/NSUserDefaults.m: On mswindows, don't count a '.exe' + extension as part of the process name when fetching defaults. + +2007-03-05 Nicola Pero + + * configure.ac: Fixed setting default GNUSTEP_*_ADMIN_APPS and + GNUSTEP_*_ADMIN_TOOLS when none is found in the config file. + * configure.ac: Print out the entire filesystem layout that is + hardcoded into gnustep-base. It makes it easier to debug + filesystem layout issues. + * configure.ac: Read, process and output the new + GNUSTEP_*_WEB_APPS variables. + * configure.ac: Do not output GNUSTEP_CONFIG_FILE variable which + is used nowhere. + * configure: Regenerated. + * Headers/Additions/GNUstepBase/config.h.in: Added definitions of + GNUSTEP_*_WEB_APPS. + * Headers/Foundation/NSPathUtilities.h (NSSearchPathDirectory): + Added GSWebApplicationsDirectory. + * Source/NSPathUtilities.m: Implemented + GSWebApplicationsDirectory. + +2007-03-05 Richard Frith-Macdonald + + * Source/NSObject.m: Try using atomic increment/decrement to get + performance of retain/release improvement in multithreaded programs. + 2007-03-05 Adam Fedor - * configure.ac, config/config.trampoline.c: Add trampoline test. - (backported). - + * configure.ac, config/config.trampoline.c: Add trampoline test. + +2007-03-05 Richard Frith-Macdonald + + * Headers/Foundation/NSAffineTransform.h: Add flags to allow + optimisation of identity and flipped coordinates(from mySTEP) + * Source/NSAffineTransform.m: Add code from mySTEP for, optimising + common cases. Fixup optimised code to use B and B consistently. + Fixup bug in optimised code for prepending matrix. + Add optimised cases for flipped transforms in appand and prepend. + Fix bug in ([-transformSize:]) which was causing problems with + negative values (MacOS-X allows negative values here, and any issues + need to be dealt with by the calling code). + +2007-03-04 Richard Frith-Macdonald + + * Headers/Foundation/NSSpellServer.h: Moved from appkit + * Source/NSSpellServer.m: Moved from appkit + * Source/GNUmakefile: Add NSSpellServer + * Headers/Foundation/Foundation.h: Add NSSpellServer + Moved NSSpellServer in from gui/appkit for MacOS-X compatibility + 2007-03-02 Richard Frith-Macdonald - * Source/GSHTTPURLHandle.m: - * Source/GSHTTPAuthentication.m: backport authentication fixes. + * Source/GSHTTPURLHandle.m: Cope with nil authentication info + * Source/GSHTTPAuthentication.m: Cope with nil credential and + catch exceptions in lock protected areas (there shouldn't be + any, but best to be safe). +2007-03-01 Nicola Pero + + * Source/NSBundle.m ([NSBundle +bundleForLibrary:]): Fixed paths + to lookup; it wouldn't work with the new filesystem layout + changes. + * configure.ac: Raise an error if we're asked to import a config + file but no such file is found. + * configure: Regenerated. + 2007-03-01 Richard Frith-Macdonald + * Source/NSZone.m: tidy indentation * Source/NSURLCredential.m: * Source/NSURLAuthenticationChallenge.m: * Source/NSURLCredentialStorage.m: * Source/NSURLResponse.m: * Source/NSURLProtocol.m: * Source/NSURLCache.m: + * Source/NSHTTPCookieStorage.m: + * Source/NSHTTPCookie.m: * Source/NSURLProtectionSpace.m: * Source/NSURLRequest.m: - backport memory initialisation fix from trunk + Use standard function to initialise and clear memory, fixing some + potential uninitialised memory errors. -2007-02-14 Richard Frith-Macdonald +2007-03-01 Richard Frith-Macdonald - * Source/NSDebug.m: - * Source/NSException.m: - Backport stackframe/stacktrace generation bugfixes from trunk + * configure.ac: Restore last reversion and fix actual bug (I hope) + which was an incorrect setting of GNUSTEP_SYSTEM_TOOLS to the + Admin subdirectory, causing relative path calculations to be wrong. + * configure: regenerated. + +2007-03-01 Richard Frith-Macdonald + + * Source/NSBundle.m: + * Source/NSPathUtilities.m: + * Headers/Foundation/NSBundle.h: + * Headers/Additions/GNUstepBase/config.h.in: + * gnustep-base.script.spec.in: + Remove internal GNUSTEP_..._ROOT variables which are no longer used. + * configure.ac: + Refrain from defining GNUSTEP_..._ROOT default values in config.h + * configure: regenerated. + +2007-02-28 Richard Frith-Macdonald + + * configure.ac: Revert part of change which guaranteed use of bad + paths on mingw ... we allow a fallback to ./GNUstep.conf instead. + of using paths from make (which is guaranteed to be wrong as the + paths it uses are for msys and we need runtime paths for the + win32 api). + * configure: Regenerated. + +2007-02-28 Nicola Pero + + * configure.ac: If no config file to import is specified, then + load the gnustep-make one in preference to the runtime config + file, which might be a relative path such as ./GNUstep.conf. On + mingw, do not set just GNUSTEP_xxx_ROOT and similar variables to + relative paths, but set all of the GNUSTEP_xxx_yyy variables by + computing relative paths using gnustep-make's scripts. + * configure: Regenerated. + +2007-02-28 Richard Frith-Macdonald + + * Source/NSObject.m: Update suggested by Larry Campbell to use 32 + locks for managing retain counts rather than just one, so reducing + lock contention when there are lots of threads running. + He reports a 50% performance improvement in his program. + +2007-02-27 Nicola Pero + + * GNUmakefile (CVS_MODULE_NAME): Do not set (exports should be + done from subversion now). + +2007-02-26 Nicola Pero + + * configure.ac: Updated for new (shorter) GNUSTEP_SYSTEM_DOC_MAN + variable names in GNUstep.conf (and similar for other DOC variable + names). + * Headers/Additions/GNUstepBase/config.h.in: Same change. + * Source/NSPathUtilities.m: Same change. + * configure: Regenerated. + +2007-02-21 Richard Frith-Macdonald + + * Source/NSCharacterSetData.h: + * Source/NSIndexSet.m: + * Source/NSCharacterSet.m: + Experimental modifications to allow an NSCharacterSet implementation + based on NSIndexSet rather than a bitmap representation. The idea is + that such an implementation, while often slower, should use much + less memory in most cases and may be a better option on handheld + devices for instance. + To enable the new code, edit to define GNUSTEP_INDEX_CHARSET near + the start of NSCharacterSet.m and build. + +2007-02-20 Richard Frith-Macdonald + + * configure.ac: Fixup to locate headers and libraries installed in + system root subdirectories again. + * configure: Regenerated. + * Source/NSNumber.m: Chance description and stringValue methods to + return 1/0 rather than YES/NO for compatibility with undocumented + MacOS-X implementation detail (bug #19010) + +2007-02-19 Nicola Pero + + * configure.ac: Updated gnustep-config calls for new/final syntax. + Do not source GNUstep.sh at the beginning. + * configure: Regenerated. + * GNUmakefile: Updated gnustep-config calls, plus set + GNUSTEP_MAKEFILES properly using :=, not =. + * Documentation/GNUmakefile: Same changes. + * Examples/GNUmakefile: Same changes. + * NSTimeZones/GNUmakefile: Same changes. + * NSTimeZones/GNUmakefile: Same changes. + * Resources/GNUmakefile: Same changes. + * Source/GNUmakefile: Same changes. + * SSL/GNUmakefile: Same changes. + * Testing/GNUmakefile: Same changes. + * Tools/GNUmakefile: Same changes. + +2007-02-19 Richard Frith-Macdonald + + * Source/NSRunLoop.m: ([performSelector:target:argument:order:modes:]) + Alter to retain target and arguments to match MacOS-X (bug #19099) + * Source/NSString.m: Fixup removal of leading path separator when + appending path componet. + * Source/NSPropertyList.m: If parsing of xml property list fails, + try again with more tolerant parser which accepts illegal characters. + Might fix bug #17112 (illegal character in nib) + +2007-02-17 Richard Frith-Macdonald + + * configure.ac: Use gnustep-config if available. + * configure: Regenerate + * Source/Makefile.postamble + * Source/GNUmakefile + * Source/Makefile.preamble + * SSL/GSSSLHandle.m + * SSL/GNUmakefile + * GNUmakefile + +2007-02-17 Sergii Stoian + + * Headers/GNUstepBase/GSFileHandle.h: Fix GSConfig.h include. + +2007-02-17 Nicola Pero + + * Source/NSBundle.m (_find_main_bundle_for_tool): New inline + function to locate tools resources in the new gnustep-make v2 + location for them. + ([NSBundle +mainBundle]): (tool resource lookup) Fixed detecting + case of an uninstalled tool to work with the gnustep-make v2 as + well. Manage the case separately so we always lookup resources + only locally for non-installed tools. For installed tools, first + use _find_main_bundle_for_tool to look in the new location for + tool resources, falling back to the old gnustep-make v1 location + if nothing is found in the new one. + +2007-02-16 Nicola Pero + + * configure.ac: Added GNUSTEP_*_ADMIN_APPS and GNUSTEP_*_ADMIN_TOOLS + variables. + * configure: Regenerated. + * Headers/Additions/GNUstepBase/config.h.in: Regenerated. + * Source/NSPathUtilities.m: Read the new config variables. + Updated NSAdminApplicationDirectory and NSAllApplicationsDirectory + for it. + +2007-02-15 Richard Frith-Macdonald + + * Source/NSTimeZone.m: + * Source/Makefile.postamble: + * Source/NSProcessInfo.m: + * Source/GNUmakefile: + * Source/NSConcreteNumber.m: + * Headers/Foundation/NSCoder.h: + * Headers/Foundation/NSByteOrder.h: + * Headers/Foundation/NSObject.h: + * Headers/Foundation/NSDecimal.h: + * Headers/Foundation/Foundation.h: + Move GSConfig.h to the GNUstepBase subdirectory so that it doesn't + appear at the top level when FHS layout is used, thus avoiding any + possible conflict with another file of the same name in /usr/include + +2007-02-15 Nicola Pero + + Important: do not update from trunk if you need stability. + * Source/NSPathUtilities.m: Updated all the path routines to work + with the new filesystem support, reading and managing the new + variables. + * configure.ac: Updated for the new filesystem support: prepare + for NSPathUtilities.m default values for all the new variables. + Make sure to avoid config files overwriting our current + GNUSTEP_MAKEFILES variable. + * configure: Regenerated. + * Headers/Additions/GNUstepBase/config.h.in: Regenerated using + autoheaders to get all the new filesystem default variable + definitions. + +2007-02-14 Nicola Pero + + * configure.ac (GNUSTEP_MAKE_CONFIG): Output errors to config.log + rather than printing them out. + + * configure.ac: Source GNUstep.sh when we need to get the current + makefile setup. Use GNUSTEP_SYSTEM_HEADERS and + GNUSTEP_SYSTEM_LIBRARIES (with backwards compatibility settings) + to compile. + * SSL/configure.ac: Same changes. + * configure: Regenerated. + * SSL/configure: Regenerated. + +2007-02-14 Nicola Pero + + We're installing gnustep-base using the new + GNUSTEP_INSTALLATION_DOMAIN mechanism, so GNUSTEP_INSTALLATION_DIR + will not even be defined in makefiles and should never be + referenced. + * Tools/Makefile.postamble (after-install): Use GNUSTEP_TOOLS, not + GNUSTEP_INSTALLATION_DIR/Tools. + +2007-02-14 Nicola Pero + + * Resources/GNUmakefile (base-resources_INSTALL_DIR): New variable + to get it working with new gnustep-make. Keep the old one around + for older gnustep-makes. + * Source/GNUmakefile (libbase-resources_INSTALL_DIR): Same change. + +2007-02-14 Roland Schwingel + + * Source/NSTimeZone.m: windows bugfix for daylight savings time. + +2007-02-13 Richard Frith-Macdonald + + * Source/NSString.m: Don't treat leading '~' in path component or + extension as a root when appending that component or extension. + +2007-02-07 Richard Frith-Macdonald + + * Source/NSException.m: Only initialise modLock where stack module + symbol handling is supported (fix bug #18938) 2007-02-06 Richard Frith-Macdonald - * Source/GSHTTPURLHandle.m: - Fix incorrect printf format string. + * Documentation/manual/manual.texi: fix format errors + * Headers/Foundation/NSException.h: document stack trace + * Documentation/Base.gsdoc: document stack trace + * Source/NSException.m: control stack trace with environment variable + Rewrite module loading code to be thread safe. + Use dladdr where available, to get offsets for dynamic library + symbols so bfi based lookup of function/method name and line + number information can work for libraries as well as the main + executable. 2007-02-05 Richard Frith-Macdonald - * Source/GSHTTPURLHandle.m: - Backport fixes from trunk. + * configure.ac: minor tweak to avoid possible inconsistency in + environment used to check LLOGN_MAX and LONG_LONG_MAX presence. + * configure: regenerate + * Source/GSHTTPURLHandle.m: always remove self as observer for all + notifications on a socket when closing it. + +2007-02-04 Richard Frith-Macdonald + + * Headers/Foundation/NSCompoundPredicate.h: + * Headers/Foundation/NSComparisonPredicate.h: + * Headers/Foundation/NSExpression.h: + Fixup version macros + * Source/NSDebug.m: Make frame functions safe. + * Source/NSException.m: Use non-symbolic stack trace if symbols + are not available. + * Source/NSIndexSet.m: Add private method for minternal use. + * Source/NSMessagePort.m: Fix error releasing uninitialised instance. 2007-01-30 Richard Frith-Macdonald - * Source/NSAutoreleasePool.m: autorelease count bugfix from trunk. + * Source/NSAutoreleasePool.m: Fix bug reporting autorlease count. 2007-01-28 Richard Frith-Macdonald - * Source/unix/NSStream.m: - * Source/win32/NSStreamWin32.m: - Backport fix to send event if error occurs in -open + * unix/NSStream.m: + * win32/NSStreamWin32.m: + Send event if an error occurs in the -open method. 2007-01-25 Richard Frith-Macdonald * Source/NSUserDefaults.m: fix failure to unlock thread lock when - unable to obtain filesystem lock. + unabel to obtain filesystem lock. 2007-01-23 Adam Fedor * Source/NSObject.m ([NSObject +initialize]): Apply BSD FPU fix - only on x86 machines (backported). + only on x86 machines. + +2007-01-23 Richard Frith-Macdonald + + * Source/win32/NSMessagePortNameServerWin32.m: + * Source/win32/NSMessagePortWin32.m: + Bugfixes to try to make win32 nameserver operation more reliable. + +2007-01-19 Richard Frith-Macdonald + + * Tools/defaults.m: Make errors go to stderr and be more informative. 2007-01-17 Richard Frith-Macdonald - * NSURLHandle.m: Backport change to make sure resourceData method - returns an autoreleased object. + * Source/NSURLHandle.m: ([resourceData]) make sure value returned + is autoreleased. + * Source/NSURL.m: Parse string a bit more strictly according to RFC -2007-01-14 Richard Frith-Macdonald +2007-01-16 Nicola Pero - * Version 1.13.1 + * configure.ac: Fixed url of build guide given in error message + when ffcall/ffi is not found. -2007-01-10 Richard Frith-Macdonald +2007-01-07 Richard Frith-Macdonald - * Source/NSDecimalNumber.m: ([initWithBytes:objCType:]) Use the - default locale to produce string. + * Source/NSNetServices.m: Locking fix pointed out by Chris. + Fixes for documentation generation. + * Source/DocMakefile: Generate documentation for new classes. + * Source/NSXMLParser.m: Fix erroneous semicolons and other + autogsdoc warnings. 2007-01-04 Richard Frith-Macdonald - * Source/NSBundle.m: backport fix for crash when initialising with - lots of frameworks. - -2007-01-02 Richard Frith-Macdonald - - * Source/NSURL.m: backport check for scheme in URL. + * Source/NSBundle.m: (initialize) tiny cleanup to avoid compiler + warnings if compiled for NeXT runtime. 2006-12-27 Richard Frith-Macdonald - * Source/GSString.m: backport keyed archiving fix. + * Source/GSString.m: Fix keyed archiving error. + +2006-12-27 Chris B. Vetter + + * Headers/Foundation/NSNetServices.h: New class + * Source/NSNetServices.m: New class + * Source/GNUmakefile: Build NSNetServices if dns_sd is available. + * configure.ac: Check for usability of dns_sd + * Headers/Foundation/Foundation.h: Include NSNetServices.h + * Headers/Additions/GNUstepBase/config.h.in: add dns_sd availability + * base.make.in: add dns_sd availability + * configure: regenerate + Support for NSNetServices implemented by Chris. + Integrated by Richard (untested). + +2006-12-27 Richard Frith-Macdonald + + * Source/NSUserDefaults.m: remove old defaults as housekeeping + observer when we reset. + * Source/NSXMLParser.m: deactivate some log messages + * Source/NSPropertyList.m: add proplist parser using NSXMLParser + to support parsing of MacOS-X property lists even when libxml2 + is not available. + +2006-12-26 Dr. H. Nikolaus Schaller, Richard Frith-Macdonald + + * Source/NSXMLParser.m: Implement reduced functionality parser if + LIBXML2 is not available. + +2006-12-26 Richard Frith-Macdonald + + * Headers/Foundation/NSValueTransformer.h: + * Source/NSValueTransformer.h: + Complete implementation. + Make thread-safe. + Document. + +2006-12-25 Dr. H. Nikolaus Schaller + + * Headers/Foundation/NSValueTransformer.h: + * Headers/Foundation/Foundation.h: + * Source/NSValueTransformer.h: + * Source/GNUmakefile: + Initial implementation of NSValueTransformer. + +2006-12-25 Richard Frith-Macdonald + + * Headers/Additions/GNUstep/GSVersionMacros.h: + Added MacOS-X compatibility version constants. + +2006-12-15 Richard Frith-Macdonald + + * Source/NSNumberFormatter.m: + Changes to match coding standards. + Small fix to get it to compile with older versions of gcc. + Various changes to avoid compiler warnings with newer gcc. + Fix problems of assigning immutable string instances to variables + typed as mutable strings. + +2006-12-15 Graham J Lee + + * Source/NSNumberFormatter.m: + Implement -stringForObjectValue: + +2006-12-15 Richard Frith-Macdonald + + * Source/mframe.m: + * Source/cifframe.m: + * Source/callframe.m: + Fix error testing whether object is an instance. + * Headers/Foundation/NSString.h: + * Headers/Foundation/NSPropertyList.h: + * Headers/Foundation/NSDistributedNotificationCenter.h: + * Headers/Foundation/NSNotificationQueue.h: + * Headers/Foundation/NSGeometry.h: + * Headers/Foundation/NSDecimal.h: + Audit all headers and make more MacOS-X enumeration constant fixups + so that we shouldn't need to break binary compatibility for additions + to the enumeration constants in future (we hope) there is stll the + possibility of apple adding constants which conflict with gnustep + extensions, though I've left a big gap between apple and gnu + values so that conflict should be unlikely unless they specifically + try to do it. + +2006-12-14 Richard Frith-Macdonald + + * Headers/Foundation/NSPathUtilities.h: + * Source/NSPathUtilities.m: + Update constants to be MacOS-X compatible, including addition of a + few more keys added in recent versions. + WARNING ... change of constants to match MacOS0X introduces binary + incompatibility, so full recompile is required. + Fix bug/misfeature of only returning paths which exist on the + filesystem ... which broke MacOS-X applications which were correctly + expecting to find a non-existent path and create it as a location + to store their resources in. + +2006-12-13 David Ayers + + * Source/mframe.m (mframe_do_call), + * Source/cifframe.m (cifframe_do_call), + * Source/callframe.m (callframe_do_call): Simplify by using + GSObjCRuntime functions. Add fallback selector search for invocations + passed to proxies. Add debug diagnostics. + +2006-12-05 Matt Rice + + * Source/NSBundle.m (+initialize): Remove usage of classes local array. + +2006-12-05 Richard Frith-Macdonald + + * NSURL.m: Check for missing scheme and return nil. + * NSString.m: Check for character conversion failure when + getting a CString. + +2006-11-30 Richard Frith-Macdonald + + * Source/GSHTTPURLHandle.m: Limit size of handle cache to 16 to + avoid increasing memory usage indefinitely if a program keeps + loading different URLs. + +2006-11-29 Richard Frith-Macdonald + + * Source/GSPrivate.h: + * Source/win32/GSFileHandleWin32.m: + * Source/Additions/GSCategories.m: + * Source/GSFileHandle.m: + Improve error checking and reporting when establishing a tcp/ip + connection. + +2006-11-27 Matt Rice + + * Source/NSObject.m: Fix typo. + * Headers/Foundation/NSException.h: Export + NSObjectInaccessibleException. 2006-11-25 Richard Frith-Macdonald - * Source/NSCalendarDate.m: backport buffer overflow fixups from trunk. - -2006-11-23 Richard Frith-Macdonald - - * Source/unix/NSStream.m: - * Source/win32/NSStreamWin32.m: - Merge bugfixes for socket reuse from trunk. - * configure.ac: - Cope with getting location of config file from more recent gnustep-make - Version: Update subminor number for bugfix release + * Source/NSCalendarDate.m: Fix buffer oiveflow vulnerability when + parsing string ... really needs major rewrite for better locale + use and full unicode support though. + * Source/GSHTTPURLHandle.m: add a little more debug. 2006-11-21 Richard Frith-Macdonald - * Source/NSURL.m: merge bugfix from trunk. + * Source/NSURL.m: + Fix potential double load of URL data. + * unix/NSStream.m: + * win32/NSStreamWin32.m: + Re-use socket ports so that programs can start up again immediately + after they have shut down. + +2006-11-20 Richard Frith-Macdonald + + * Source/NSCalendarDate.m: Fix to parse timezone names as being + whitespace delimited. + +2006-11-19 Richard Frith-Macdonald + + * Source/NSAffineTransform.m: Adapted from old gui code + * Headers/Foundation/NSAffineTransform.h: ditto + * Source/GNUmakefile: Add NSAffineTransform. + * Headers/Foundation/Foundation.h: ditto + Add NSAffineTransform for MacOS-X compatibility ... gui specific + code is added using a category in the gui library. 2006-11-18 Richard Frith-Macdonald - * Source/NSCalendarDate.m: - * Source/NSPropertyList.m: - * Source/GSHTTPURLHandle.m: - * Source/NSString.m: - * Source/NSDecimalNumber.m: + * Source/Additions/GSXML.m: ([setRootNode:]) Add checks for invalid + argument and improve documentation. + * Source/GSHTTPURLHandle.m: don't keep unecessary read operation in + progress on idle connection. + +2006-11-15 Nicola Pero + + Notice: you should now use 'make DESTDIR=/tmp/xxx install' if you + want to relocate all the installation into /tmp/xxx/ + * Makefile.postamble: Use DESTDIR instead of INSTALL_ROOT_DIR + everywhere. + +2006-11-15 Nicola Pero + + * Documentation/GNUmakefile (GNUSTEP_INSTALLATION_DOMAIN): Use + GNUSTEP_INSTALLATION_DOMAIN instead of GNUSTEP_INSTALLATION_DIR. + * Documentation/General/GNUmakefile: Same change. + * NSCharacterSets/GNUmakefile: Same change. + * NSTimeZones/GNUmakefile: Same change. + * Resources/GNUmakefile: Same change. + * Source/GNUmakefile: Same change. + * SSL/GNUmakefile: Same change. + * Tools/GNUmakefile: Same change. + +2006-11-14 Richard Frith-Macdonald + + * Source/GSHTTPURLHandle.m: fix bug detecting eof in read. + Add code to check for eof immediately before writing. + +2006-11-14 Adam Fedor + + * Headers/Additions/GNUstepBase/GSCategories.h: Add GSOnce macros. + * Source/Additions/GSFunctions.m: Add GSCategories.h + +2006-11-13 Richard Frith-Macdonald + + * Source/NSCalendarDate.m: Fix a few string parsing errors (check that + string matches format in MacOS-X compatible manner). + * Source/GSHTTPURLHandle.m: try to detect socket being closed by + remote end of connection before we try writing to it. + +2006-11-12 Richard Frith-Macdonald + + * Source/GSHTTPURLHandle.m: Clear pageInfo before load. + Improve checking for dropped connections. + +2006-11-08 Richard Frith-Macdonald + + Source/NSIndexSet.m: ([addIndexesInRange:]) + Fix for case when added range lies within existing range. + +2006-11-08 Richard Frith-Macdonald + + * Source/Additions/GSXML.m: ([stringByEscapingXML]) Fix bug causing + newline characters to be removed from escaped strings. + +2006-11-07 David Wetzel + * Source/Additions/GSXML.m: - * Source/Additions/GSMime.m: - * Source/NSConnection.m: - * Source/NSIndexSet.m: - * Source/NSSortDescriptor.m: - * Tools/AGSHtml.m: + Fix error setting start and end element for SAX. + +2006-11-06 Richard Frith-Macdonald + + * Source/NSObject.m: Use %p to print address in description. + * Documentation/General/OpenStepCompliance.gsdoc: + * Documentation/General/Debugging.gsdoc: + * Tools/gsdoc.gsdoc: + * Tools/gdomap.gsdoc: + * Tools/gsdoc-1_0_1.dtd: + * Tools/gsdoc-1_0_1.rnc: * Tools/autogsdoc.m: + * Tools/AGSOutput.m: + * Tools/autogsdoc.1: + * Tools/BaseTools.gsdoc: + Minor documentation version fixups. + +2006-11-03 Richard Frith-Macdonald + + * Source/NSString.m: ([stringByAddingPercentEscapesUsingEncoding:]) + Improved documentation. + * Source/Additions/GSMime.m: Add more charset mappings for where the + hyphen after the 'iso' has been omitted. + +2006-11-02 Richard Frith-Macdonald + + * Source/NSString.m: ([stringByAddingPercentEscapesUsingEncoding:]) + Make the set of characters escaped compatible with MacOS-X (10.4). + +2006-11-01 Richard Frith-Macdonald + + * Source/NSSortDescriptor.m; minor tidyups + * Headers/Foundation/NSSortDescriptor.h: add documentation + * Headers/Foundation/NSKeyValueCoding.h: improve version macros + * Headers/Foundation/NSKeyValueObserving.h: add include for NSArray + +2006-10-31 Richard Frith-Macdonald + + * Source/NSSocketPortNameServer.m: + * Source/NSRunLoop.m: + * Source/NSDebug.m: + * Source/unix/GSRunLoopCtxt.m: + * Source/NSPort.m: + * Source/NSConcreteNumber.h: + * Source/win32/GSRunLoopCtxt.m: + * Source/NSThread.m: + * Source/NSSerializer.m: + * Documentation/Base.gsdoc: + * Headers/Foundation/NSTimeZone.h: + * Headers/Foundation/NSHashTable.h: + * Headers/Foundation/NSCoder.h: + * Headers/Foundation/NSRange.h: + * Headers/Foundation/NSURLCredential.h: + * Headers/Foundation/NSHTTPCookieStorage.h: + * Headers/Foundation/NSException.h: + * Headers/Foundation/NSByteOrder.h: + * Headers/Foundation/NSPortCoder.h: + * Headers/Foundation/NSURL.h: + * Headers/Foundation/NSURLAuthenticationChallenge.h: + * Headers/Foundation/NSCompoundPredicate.h: + * Headers/Foundation/NSObject.h: + * Headers/Foundation/NSString.h: + * Headers/Foundation/NSCalendarDate.h: + * Headers/Foundation/NSDecimalNumber.h: + * Headers/Foundation/NSKeyValueCoding.h: + * Headers/Foundation/NSBundle.h: + * Headers/Foundation/NSSerialization.h: + * Headers/Foundation/NSURLHandle.h: + * Headers/Foundation/NSPropertyList.h: + * Headers/Foundation/NSTimer.h: + * Headers/Foundation/NSNotification.h: + * Headers/Foundation/NSPathUtilities.h: + * Headers/Foundation/NSScanner.h: + * Headers/Foundation/NSProcessInfo.h: + * Headers/Foundation/NSDistributedNotificationCenter.h: + * Headers/Foundation/NSNotificationQueue.h: + * Headers/Foundation/NSGeometry.h: + * Headers/Foundation/NSStream.h: + * Headers/Foundation/NSComparisonPredicate.h: + * Headers/Foundation/NSDecimal.h: + * Headers/Foundation/NSAttributedString.h: + * Headers/Foundation/NSRunLoop.h: + * Headers/Foundation/NSConnection.h: + * Headers/Foundation/NSUndoManager.h: + * Headers/Foundation/NSDateFormatter.h: + * Headers/Foundation/NSMethodSignature.h: + * Headers/Foundation/NSFormatter.h: + * Headers/Foundation/NSAutoreleasePool.h: + * Headers/Foundation/NSUserDefaults.h: + * Headers/Foundation/NSThread.h: + * Headers/Foundation/NSHTTPCookie.h: + * Headers/Foundation/NSData.h: + * Headers/Foundation/NSURLError.h: + * Headers/Foundation/NSHost.h: + * Headers/Foundation/NSDate.h: + * Headers/Foundation/NSArray.h: + * Headers/Foundation/NSObjCRuntime.h: + * Headers/Foundation/NSProxy.h: + * Headers/Foundation/NSURLProtectionSpace.h: + * Headers/Foundation/NSKeyedArchiver.h: + * Headers/Foundation/NSDebug.h: + * Headers/Foundation/NSProtocolChecker.h: + * Headers/Foundation/NSError.h: + * Headers/Foundation/NSPortMessage.h: + * Headers/Foundation/NSURLDownload.h: + * Headers/Foundation/NSFileHandle.h: + * Headers/Foundation/NSDistributedLock.h: + * Headers/Foundation/NSPredicate.h: * Headers/Foundation/NSKeyValueObserving.h: - Backport bugfixes from trunk + * Headers/Foundation/NSDictionary.h: + * Headers/Foundation/NSClassDescription.h: + * Headers/Foundation/NSNull.h: + * Headers/Foundation/NSZone.h: + * Headers/Foundation/NSURLRequest.h: + * Headers/Foundation/NSValue.h: + * Headers/Foundation/NSURLCredentialStorage.h: + * Headers/Foundation/NSIndexSet.h: + * Headers/Foundation/NSPort.h: + * Headers/Foundation/NSSortDescriptor.h: + * Headers/Foundation/NSLock.h: + * Headers/Foundation/NSSet.h: + * Headers/Foundation/NSDistantObject.h: + * Headers/Foundation/NSExpression.h: + * Headers/Foundation/NSTask.h: + * Headers/Foundation/NSArchiver.h: + * Headers/Foundation/Foundation.h: + * Headers/Foundation/NSCharacterSet.h: + * Headers/Foundation/NSInvocation.h: + * Headers/Foundation/NSFileManager.h: + * Headers/Foundation/NSUtilities.h: + * Headers/Foundation/NSPortNameServer.h: + * Headers/Foundation/NSNumberFormatter.h: + * Headers/Foundation/NSXMLParser.h: + * Headers/Foundation/NSEnumerator.h: + * Headers/Foundation/NSURLResponse.h: + * Headers/Foundation/NSURLConnection.h: + * Headers/Foundation/NSIndexPath.h: + * Headers/Foundation/NSURLProtocol.h: + * Headers/Foundation/NSMapTable.h: + * Headers/Foundation/NSURLCache.h: + * Headers/Additions/GNUstepBase/GSXML.h: + * Headers/Additions/GNUstepBase/behavior.h: + * Headers/Additions/GNUstepBase/GSFunctions.h: + * Headers/Additions/GNUstepBase/GSConfig.h.in: + * Headers/Additions/GNUstepBase/GSObjCRuntime.h: + * Headers/Additions/GNUstepBase/GSCategories.h: + * Headers/Additions/GNUstepBase/GSIMap.h: + * Headers/Additions/GNUstepBase/GSIArray.h: + * Headers/Additions/GNUstepBase/GSMime.h: + * Headers/Additions/GNUstepBase/Unicode.h: + Ensure all headers have up to date version macros included. + Update to remove obsolete version macro information. + Tidy FSF address for consistency. + Tidy per-heaader inclusion guard preprocessor definitions. + +2006-10-30 Richard Frith-Macdonald + + * Headers/Foundation/NSUserDefaults.h: + * Source/NSUserDefaults.m: + Update comments into headers and tag methods with API version + information. + +2006-10-29 Richard Frith-Macdonald + + * Source/GSPrivate.h: + * Source/Additions/Unicode.m: + * Source/GSeq.h: + * Headers/Additions/GNUstepBase/Unicode.h: + runi_cop should be private in future. + remove some redundant code. + * Source/Additions/GSMime.m: Add support for some more character + encodings. + Fix uninitialised variable compiler failed to warn about. + +2006-10-27 Richard Frith-Macdonald + + * Source/NSTask.m: GSPrivateCheckTasks() retain terminated task + while handling termination process and notification to prevent + possible thread safety issue spotted by Wim. + +2006-10-26 Richard Frith-Macdonald + + * Source/NSPropertyList.m: use declaration of GSArray from GSPrivate.h + * Source/GSArray.m: ditto + * Source/NSArray.m: ditto + * Source/NSSerializer.m ditto + * Source/NSConcreteNumberTemplate.m: Use private function to get hash. + * Source/NSConcreteNumber.m: ditto + * Source/NSNumber.m: ditto + * Source/GSPrivate.h: Add hash functions. + * Headers/Foundation/NSSortDescriptor.h: Add a little documentation. + * Source/NSSortDescriptor.m: Implement better hash/isEqual as + suggested by David. Complete rewrite of sorting to avoid lots of + heap memory operations ... should be much much faster. + +2006-10-25 Richard Frith-Macdonald + + * configure.ac: Define HAVE_VISIBILITY_ATTRIBUTE if gcc's visibility + attribute is both present in the version being used and working on + the current platform. + * configure: Regenerate + * Headers/Additions/GNUstepBase/config.h.in: Regenerate + * Source/GSPrivate.h: Only use the visibility attribute if it is + available. Avoids warnings (and link errors in at least one case) + on systems where it is not fully supported by gcc yet. + * Headers/Foundation/NSSortDescriptor.h: Tidy and fix macros marking + macos compatibility. + * Source/NSSortDescriptor.m: Fix to have usable hash and isEqual + (bug #18107). + +2006-10-23 Richard Frith-Macdonald + + * Source/NSCalendarDate: when adding offset to a date, work in + the timezone for the date rather than in GMT ... fixes bug #18088 + * Source/NSBundle.m: + * Source/NSPathUtilities.m: + * Source/NSProcessInfo.m: + * Source/preface.m: + * Source/NSCallBacks.h: + * Source/GSPrivate.h: + * Source/NSFileManager.m: + * Source/objc-load.h: + * Source/objc-load.m: + * Headers/Additions/GNUstepBase/preface.h.in: + More cleanups hiding private functions and removing a few unused bits. + +2006-10-20 Richard Frith-Macdonald + + * Source/Additions/GSPrivate.m: + * Source/GSFormat.h: + Deleted unused files. + * Headers/Foundation/NSError.h: + * Source/NSError.m: + Updated to current MacOS-X spec. + * Source/NSIndexPath.m: + * Source/NSSocketPortNameServer.m: + * Source/NSTimeZone.m: + * Source/NSHashTable.m: + * Source/NSBundle.m: + * Source/NSPropertyList.m: + * Source/libgnustep-base-entry.m: + * Source/GSConcreteValueTemplate.m: + * Source/NSScanner.m: + * Source/NSProcessInfo.m: + * Source/NSGeometry.m: + * Source/NSSocketPort.m: + * Source/NSUndoManager.m: + * Source/NSMethodSignature.m: + * Source/NSFormatter.m: + * Source/NSUserDefaults.m: + * Source/NSArray.m: + * Source/NSMessagePortNameServer.m: + * Source/objc-gnu2next.m: + * Source/GSStream.m: + * Source/NSDebug.m: + * Source/unix/GSRunLoopCtxt.m: + * Source/GSConcreteValue.m: + * Source/NSDistributedLock.m: + * Source/NSFileHandle.m: + * Source/preface.m: + * Source/NSAssertionHandler.m: + * Source/NSConcreteNumberTemplate.m: + * Source/GSHTTPURLHandle.m: + * Source/NSZone.m: + * Source/NSCallBacks.m: + * Source/NSMessagePort.m: + * Source/GSDictionary.m: + * Source/GSPrivate.h: + * Source/GSCountedSet.m: + * Source/win32/GSFileHandleWin32.m: + * Source/win32/GSRunLoopCtxt.m: + * Source/win32/NSMessagePortWin32.m: + * Source/win32/NSStreamWin32.m: + * Source/NSFileManager.m: + * Source/NSConcreteNumber.m: + * Source/NSNotificationCenter.m: + * Source/externs.m: + * Source/NSRange.m: + * Source/NSException.m: + * Source/NSCopyObject.m: + * Source/mframe.m: + * Source/NSObject.m: + * Source/NSString.m: + * Source/Additions/Unicode.m: + * Source/Additions/GNUmakefile: + * Source/Additions/GSCompatibility.m: + * Source/Additions/GSCategories.m: + * Source/GSSet.m: + * Source/GSString.m: + * Source/NSThread.m: + * Source/NSData.m: + * Source/NSHost.m: + * Source/NSProxy.m: + * Source/NSProtocolChecker.m: + * Source/NSPipe.m: + * Source/GSValue.m: + * Source/NSDictionary.m: + * Source/NSClassDescription.m: + * Source/NSSerializer.m: + * Source/NSNull.m: + * Source/NSValue.m: + * Source/NSCountedSet.m: + * Source/NSLog.m: + * Source/GSFormat.m: + * Source/NSIndexSet.m: + * Source/GSFileHandle.m: + * Source/NSLock.m: + * Source/NSDistantObject.m: + * Source/NSTask.m: + * Source/NSPortNameServer.m: + * Source/NSNumberFormatter.m: + * Source/NSXMLParser.m: + * Source/GSFTPURLHandle.m: + * Source/NSEnumerator.m: + * Source/GSURLPrivate.h: + * SSL/GSSSLHandle.m: + Move from GSPrivate class to GSPrivate functions as majority prefer + that. Make some more private functions use GSPrivate prefix and be + unlinkable outside base. Rationalise error string generation. + Tidy up FSF address in comments. + +2006-10-19 Richard Frith-Macdonald + + * Documentation/manual/DistributedObjects.texi: Update for current API + * Source/NSNotificationQueue.m: + * Source/NSSocketPort.m: + * Source/NSRunLoop.m: + * Source/NSUserDefaults.m: + * Source/NSMessagePortNameServer.m: + * Source/NSDebug.m: + * Source/unix/GSRunLoopCtxt.m: + * Source/GSPrivate.h: + * Source/win32/GSFileHandleWin32.m: + * Source/win32/GSRunLoopCtxt.m: + * Source/NSCoder.m: + * Source/Additions/GSPrivate.m: + * Source/NSAutoreleasePool.m: + * Source/NSTask.m: + * Headers/Foundation/NSCoder.h: + Remove long deprecated coder extensions (old libobjects + compatibility). + Hide some internal functions. + Make some values static. + Make function to obtain locale dictionary thread safe. + +2006-10-19 Matt Rice + + * Source/NSBundle.m (_find_framework): initialize file_name variable. + +2006-10-19 Richard Frith-Macdonald + + * Source/NSBundle.m: Strip path extension from main bundle name on + cygwin. + * Headers/Foundation/NSPortNameServer.h: Improve documentation + +2006-10-18 Richard Frith-Macdonald + + * Source/Makefile.postamble: + Remove use of UNICODE_HEADERS which appears to beave been breaking + solaris build. + +2006-10-18 Richard Frith-Macdonald + + * Source/Additions/GSPrivate.m: + * Source/Additions/Unicode.m: + * Source/GSPrivate.h: + * Source/NSArray.m: + * Source/NSCalendarDate.m: + * Source/NSDate.m: + * Source/NSDecimalNumber.m: + * Source/NSDictionary.m: + * Source/NSNotification.m: + * Source/NSObject.m: + * Source/NSProcessInfo.m: + * Source/NSScanner.m: + * Source/NSString.m: + * Source/NSUserDefaults.m: + Experiments with gcc attribute for making functions inaccessible + outside the library ... new experimental function + GSPrivateDefaultLocale() declared in GSPrivate.h, implemented in + Additions/GSPrivate.m seems to work and to be invisible to the linker + for external apps. + +2006-10-17 Richard Frith-Macdonald + + * Source/NSPropertyList.m: + Fix error writing negative numbers to property list. + +2006-10-16 Richard Frith-Macdonald + + * Source/GSFFCallInvocation.m: + * Source/GSFFIInvocation.m: + * Source/GSPrivate.h: + * Source/Additions/GNUmakefile: + * Source/Additions/GSPrivate.m: + * Source/Additions/GSCategories.m: + Minor further work simplifying and getting rid of unnecessary + external symbols etc. + +2006-10-13 Richard Frith-Macdonald + + * Source/NSFileHandle.m: Look for SSL bundle in any domain. + * Source/NSTimer.m: Fix minor documentation error. + +2006-10-11 Nicola Pero + + * GNUmakefile (GNUSTEP_INSTALLATION_DOMAIN): Use + GNUSTEP_INSTALLATION_DOMAIN instead of GNUSTEP_INSTALLATION_DIR. + +2006-10-11 Richard Frith-Macdonald + + * Source/externs.m: + * Source/Additions/Unicode.m: + * Source/NSDecimal.m: + * Source/GSFormat.m: + * Testing/tcpport-server.m: + * Testing/exported-strings.m: + Make many globals static, remove some obsolete variables etc. + +2006-10-11 Nicola Pero + + * SSL/Makefile.postamble (after-distclean): Remove all configure + generated files. + (config.mak): Run config.status, not ../config.status. + ($(GNUSTEP_TARGET_DIR)/config.h): Run config.status first. Do not + try to move config.h into a target specific dir if the target dir + is '.'. + (config.status): New rule to recreate it. + +2006-10-11 Nicola Pero + + * Source/Additions/Makefile.preamble (ADDITIONAL_INCLUDE_DIRS): + Added -I.. so that the compiler finds GSPrivate.h when it's using + the non-flattened layout, and it compiles again. + * SSL/Makefile.preamble (ADDITIONAL_INCLUDE_DIRS): Added + -I../Source for the same reason. + +2006-10-10 Richard Frith-Macdonald + + * Source/NSDecimalNumber.m: Implement coding/decoding + +2006-10-09 Nicola Pero + + * GNUmakefile: Do not include GNUmakefile.local. + +2006-10-09 Richard Frith-Macdonald + + * Source/GSCompatibility.m: Removed ... no longer used + * Source/GNUmakefile: Remove GSCompatibility.m + * Source/NSGeometry.m: + * Source/NSArray.m: + * Source/NSDictionary.m: + Update to get rid of a couple of functions which were not really + needed, slimming down global symbols a bit more. + +2006-10-09 Richard Frith-Macdonald + + * Source/Additions/GSObjCRuntime.m: + * Headers/Additions/GNUstepBase/GSObjCRuntime.h: + Remove previously deprecated functionality. + * Documentation/TypesAndConstants.gsdoc: + * Documentation/ReleaseNotes.gsdoc: + * Documentation/Functions.gsdoc: + * Documentation/BaseAdditions.gsdoc: + * Documentation/Base.gsdoc: + * ChangeLog: + * Tools/AGSHtml.m: + * Tools/AGSParser.m: + * Tools/autogsdoc.m: + * Tools/AGSOutput.m: + Update/improve version/deprecation reporting. + +2006-10-09 Richard Frith-Macdonald + + * Headers/Additions/GNUstepBase/unicode: + Moved to Source/Additions/unicode + * Source/NSSocketPortNameServer.m: + * Source/GSLocale.m: + * Source/NSTimeZone.m: + * Source/GSCompatibility.m: + * Source/NSCalendarDate.m: + * Source/NSBundle.m: + * Source/NSPropertyList.m: + * Source/NSPathUtilities.m: + * Source/NSScanner.m: + * Source/NSProcessInfo.m: + * Source/GNUmakefile: + * Source/NSSocketPort.m: + * Source/NSUserDefaults.m: + * Source/GSFFCallInvocation.m: + * Source/NSArray.m: + * Source/GSStream.m: + * Source/NSKeyedArchiver.m: + * Source/NSDebug.m: + * Source/unix/GSRunLoopCtxt.m: + * Source/NSDistributedLock.m: + * Source/GSHTTPURLHandle.m: + * Source/NSMessagePort.m: + * Source/GSPrivate.h: + * Source/win32/NSMessagePortNameServerWin32.m: + * Source/win32/GSFileHandleWin32.m: + * Source/win32/NSUserDefaultsWin32.m: + * Source/win32/GSRunLoopCtxt.m: + * Source/win32/NSMessagePortWin32.m: + * Source/win32/NSStreamWin32.m: + * Source/NSInvocation.m: + * Source/NSFileManager.m: + * Source/objc-load.m: + * Source/NSException.m: + * Source/NSString.m: + * Source/NSObject.m: + * Source/NSDecimalNumber.m: + * Source/Additions/Unicode.m: + * Source/Additions/GSXML.m: + * Source/Additions/GSFunctions.m: + * Source/Additions/GSCompatibility.m: + * Source/Additions/GSCategories.m: + * Source/NSDecimal.m: + * Source/GSString.m: + * Source/NSDateFormatter.m: + * Source/NSThread.m: + * Source/NSData.m: + * Source/NSHost.m: + * Source/NSDate.m: + * Source/NSObjCRuntime.m: + * Source/NSPipe.m: + * Source/NSDictionary.m: + * Source/NSLog.m: + * Source/GSFormat.m: + * Source/GSFileHandle.m: + * Source/NSTask.m: + * Source/NSArchiver.m: + * Source/GSFTPURLHandle.m: + * SSL/GSSSLHandle.m: + * Headers/Foundation/NSException.h: + * Headers/Additions/GNUstepBase/GSFunctions.h: + * Headers/Additions/GNUstepBase/GSObjCRuntime.h: + * Headers/Additions/GNUstepBase/Unicode.h: + * Tools/xmlparse.m: + * Tools/defaults.m: + * Tools/locale_alias.m: + * Tools/Makefile.preamble: + * Tools/AGSParser.m: + * Tools/make_strings/make_strings.m: + * Tools/pl.m: + * Testing/tcpport-server.m: + * Testing/exported-strings.m: + * Testing/call.m: + * Testing/nsconnection_server.m: + * Testing/benchmark.m: + * Testing/tcpport-client.m: + Continuing effort to reduce global namespace pollution ... made many + external variables static (particuarly unicode tables). Changed + several global functions to be methods of a private internal class. + Also updated several usages of deprecated cString methods to use + either UTF8 methods or cString...encoding methods as seemed most + appropriate and/or simplest. + +2006-10-06 Fred Kiefer + + * Source/Additions/GSMime.m(GSMimeDocument +initialize): Corrected + small bug in last patch. + +2006-10-05 Richard Frith-Macdonald + + * Source/Additions/GSMime.m: Add a couple more charset mappings. + * Source/NSRunLoop.m: Move some variables to GSRunLoopCtxt.m + * Source/GSHTTPURLHandle.m: Make a global static + * Source/NSPort.m: Make two globals static + * Source/unix/GSRunLoopCtxt.m: Make variable static. + * Source/win32/GSRunLoopCtxt.m: Make variable static. + +2006-10-04 Richard Frith-Macdonald + + * Source/GSHTTPURLHandle.m: + * Source/NSHTTPCookieStorage.m: + * Source/GSHTTPAuthentication.m: Add a little checking for nil/invalid + arguments. Make parsing of authentication a little more tolerant. + +2006-10-03 Richard Frith-Macdonald + + * Version: Bump to version for next release. + * configure.ac: Check for utsname + * configure: Regenerate + * Headers/Additions/GNUstepBase/config.h.in: Regenerate + * Headers/Foundation/NSObject.h: Small documentaion improvement + * Headers/Foundation/NSProcessInfo.h: Add documentation and update. + * Source/NSProcessInfo.m: Moved documentation to header, clean up + and complete operating system code. + * Testing/nsprocessinfo.m: Trivial test updates. Avoid use of cString + +2006-10-02 Nicola Pero + + More work on having the default flattened gnustep build with just + GNUSTEP_MAKEFILES set. Non-flattened builds will still require + sourcing GNUstep.sh before configure instead. + + * configure.ac: Use new variable GNUSTEP_IS_FLATTENED instead + of GNUSTEP_FLATTENED, defaulting now to 'yes'. To build + non-flattened you have to source GNUstep.sh first. + * configure.ac (config.make): When determining objc threading + flags in non-flattened mode, look for config.make in a + library-combo subdir since that's where it is installed by + gnustep-make now. + * configure.ac: Extended the error message when the GNUstep conf + file is not found. + * configure: Regenerated. + + * SSL/configure.ac: Use GNUSTEP_IS_FLATTENED instead of + GNUSTEP_FLATTENED. + * SSL/configure: Regenerated. + + * Source/GNUmakefile: Renamed -DGNUSTEP_FLATTENED to + -DGNUSTEP_IS_FLATTENED. This is just for consistency + with the new gnustep-make variable name. + * Source/NSPathUtilities.m: Same changes. + +2006-09-28 Richard Frith-Macdonald + + * Source/NSBundle.m: Fix for buffer resize error when registering + framework info, as suggested by Andreas Hoschler. + +2006-09-26 Richard Frith-Macdonald + + * Source/NSString.m: ([stringByAddingPercentEscapesUsingEncoding:]) + Fix to escape '@' (in fact anything not unreserved acording to + RFC2396) + * Source/NSPathUtilities.m: Fix missing include. + +2006-09-21 Richard Frith-Macdonald + + * Source/NSProcessInfo.m: ([-operatingSystemName]) conform to + MacOS-X and return NSMACHOperatingSystem rather than darwin etc. + +2006-09-18 Nicola Pero + + * configure.ac (GNUSTEP_MAKE_CONFIG): Get this config from + config-noarch.make (requires gnustep-make > 1.13.0). If failing, + fall back to taking it from $GNUSTEP_MAKEFILES/config.make as it + was done before (works with gnustep-make < 1.13.0 only though). + * configure: Regenerated. + +2006-09-13 Richard Frith-Macdonald + + * Source/Additions/GSXML.m: Add hack to recognize apple plist info + and use the GNUstep plist DTD instead if necessary. + +2006-09-13 Richard Frith-Macdonald + + * Headers/Foundation/NSTimeZone.h: + * Headers/Foundation/NSHashTable.h: + * Headers/Foundation/NSRange.h: + * Headers/Foundation/NSCoder.h: + * Headers/Foundation/NSURLCredential.h: + * Headers/Foundation/NSHTTPCookieStorage.h: + * Headers/Foundation/NSException.h: + * Headers/Foundation/NSByteOrder.h: + * Headers/Foundation/NSPortCoder.h: + * Headers/Foundation/NSURL.h: + * Headers/Foundation/NSCompoundPredicate.h: + * Headers/Foundation/NSURLAuthenticationChallenge.h: + * Headers/Foundation/NSString.h: + * Headers/Foundation/NSObject.h: + * Headers/Foundation/NSCalendarDate.h: + * Headers/Foundation/NSDecimalNumber.h: + * Headers/Foundation/NSBundle.h: + * Headers/Foundation/NSKeyValueCoding.h: + * Headers/Foundation/NSSerialization.h: + * Headers/Foundation/NSURLHandle.h: + * Headers/Foundation/NSPropertyList.h: + * Headers/Foundation/NSTimer.h: + * Headers/Foundation/NSNotification.h: + * Headers/Foundation/NSPathUtilities.h: + * Headers/Foundation/NSScanner.h: + * Headers/Foundation/NSProcessInfo.h: + * Headers/Foundation/NSDistributedNotificationCenter.h: + * Headers/Foundation/NSNotificationQueue.h: + * Headers/Foundation/NSGeometry.h: + * Headers/Foundation/NSStream.h: + * Headers/Foundation/NSComparisonPredicate.h: + * Headers/Foundation/NSDecimal.h: + * Headers/Foundation/NSRunLoop.h: + * Headers/Foundation/NSAttributedString.h: + * Headers/Foundation/NSConnection.h: + * Headers/Foundation/NSUndoManager.h: + * Headers/Foundation/NSDateFormatter.h: + * Headers/Foundation/NSMethodSignature.h: + * Headers/Foundation/NSAutoreleasePool.h: + * Headers/Foundation/NSFormatter.h: + * Headers/Foundation/NSUserDefaults.h: + * Headers/Foundation/NSThread.h: + * Headers/Foundation/NSHTTPCookie.h: + * Headers/Foundation/NSData.h: + * Headers/Foundation/NSURLError.h: + * Headers/Foundation/NSDate.h: + * Headers/Foundation/NSHost.h: + * Headers/Foundation/NSArray.h: + * Headers/Foundation/NSProxy.h: + * Headers/Foundation/NSObjCRuntime.h: + * Headers/Foundation/NSURLProtectionSpace.h: + * Headers/Foundation/NSKeyedArchiver.h: + * Headers/Foundation/NSProtocolChecker.h: + * Headers/Foundation/NSDebug.h: + * Headers/Foundation/NSPortMessage.h: + * Headers/Foundation/NSError.h: + * Headers/Foundation/NSURLDownload.h: + * Headers/Foundation/NSDistributedLock.h: + * Headers/Foundation/NSFileHandle.h: + * Headers/Foundation/NSPredicate.h: + * Headers/Foundation/NSKeyValueObserving.h: + * Headers/Foundation/NSDictionary.h: + * Headers/Foundation/NSClassDescription.h: + * Headers/Foundation/NSNull.h: + * Headers/Foundation/NSZone.h: + * Headers/Foundation/NSURLRequest.h: + * Headers/Foundation/NSValue.h: + * Headers/Foundation/NSURLCredentialStorage.h: + * Headers/Foundation/NSIndexSet.h: + * Headers/Foundation/NSPort.h: + * Headers/Foundation/NSSortDescriptor.h: + * Headers/Foundation/NSLock.h: + * Headers/Foundation/NSSet.h: + * Headers/Foundation/NSDistantObject.h: + * Headers/Foundation/NSExpression.h: + * Headers/Foundation/NSTask.h: + * Headers/Foundation/NSArchiver.h: + * Headers/Foundation/NSCharacterSet.h: + * Headers/Foundation/NSInvocation.h: + * Headers/Foundation/NSFileManager.h: + * Headers/Foundation/NSPortNameServer.h: + * Headers/Foundation/NSNumberFormatter.h: + * Headers/Foundation/NSXMLParser.h: + * Headers/Foundation/NSEnumerator.h: + * Headers/Foundation/NSURLResponse.h: + * Headers/Foundation/NSURLConnection.h: + * Headers/Foundation/NSIndexPath.h: + * Headers/Foundation/NSURLProtocol.h: + * Headers/Foundation/NSMapTable.h: + * Headers/Foundation/NSURLCache.h: + * Headers/Additions/GNUstepBase/GSLocale.h: + * Headers/Additions/GNUstepBase/GSXML.h: + * Headers/Additions/GNUstepBase/DistributedObjects.h: + * Headers/Additions/GNUstepBase/behavior.h: + * Headers/Additions/GNUstepBase/GSFunctions.h: + * Headers/Additions/GNUstepBase/GSObjCRuntime.h: + * Headers/Additions/GNUstepBase/GSCategories.h: + * Headers/Additions/GNUstepBase/GCObject.h: + * Headers/Additions/GNUstepBase/GSIMap.h: + * Headers/Additions/GNUstepBase/GSIArray.h: + * Headers/Additions/GNUstepBase/GSMime.h: + * Headers/Additions/GNUstepBase/GSUnion.h: + * Headers/Additions/GNUstepBase/GSLock.h: + * Headers/Additions/GNUstepBase/GSFileHandle.h: + * Headers/Additions/GNUstepBase/GNUstep.h: + * Headers/Additions/GNUstepBase/objc-gnu2next.h: + * Headers/Additions/GNUstepBase/Unicode.h: + Bracket with 'extern "C"' for inclusion in Objective-C++ programs. + * Source/NSNotificationCenter.m: Remove deprecated method. + +2006-09-13 Richard Frith-Macdonald + + * Source/Additions/GSMime.m: When decoding a corrupt encoded word + in a header, abandon processing of the header without appending + any decoded data. + * Headers/Foundation/NSBundle.h: + * Source/NSBundle.m: + ([pathForResource:ofType:inDirectory:forLocalization:]) implement. + +2006-09-10 Richard Frith-Macdonald + + * Source/NSTimeZone.m: Remove unnecessary check on file name as + Roland Schwingel reported that it caught legitimate files on windows. + * Source/NSMessagePort.m: + * Source/NSSocketPort.m: + * Source/NSIndexPath.m: + * Source/NSBundle.m: + Protect -release with lock and remove object from global table within + protected region, to avoid possible double deallocation in a + multithreaded process. + * Source/unix/NSStream.m: If socklen_t is not defined, assume uint32_t + +2006-09-09 Richard Frith-Macdonald + + * Source/win32/NSMessagePortWin32.m: Restructure to try to avoid + deadlock reported by Wim. Also implement -release to remove port + from name table so that another thread can't find it in the window + between checking the refcount end deallocation. + +2006-09-07 Richard Frith-Macdonald + + * Headers/Foundation/NSObject.h: Fix incorrect backward compatibility + setting for openstep version. + * Source/NSObject.m: minor tweak ... put debugging code in the object + reference counting function rather than the release method. + * Source/NSConnection.m: Change release implementation for better + protection of global connection table management. + +2006-09-06 Richard Frith-Macdonald + + * Source/NSConnection.m: ([release]) protect with connection table + lock to prevent an other thread grabbing the connection while we + are deallocating it. Bug reported by Wim Oudshoorn. 2006-08-28 Adam Fedor diff --git a/Documentation/Base.gsdoc b/Documentation/Base.gsdoc index f348ee9c2..69c5ddc1e 100644 --- a/Documentation/Base.gsdoc +++ b/Documentation/Base.gsdoc @@ -1,5 +1,5 @@ - + + *

+ * + *

+ * + *

+ *
+ *

+ * [NSNetService] lets you publish a network service in a domain using + * multicast DNS. Additionally, it lets you resolve a network service that + * was discovered by [NSNetServiceBrowser]. + *

+ */ + +@interface NSNetService : NSObject +{ + @private + void * _netService; + id _delegate; + void * _reserved; +} + ++ (NSData *) dataFromTXTRecordDictionary: (NSDictionary *) txtDictionary; ++ (NSDictionary *) dictionaryFromTXTRecordData: (NSData *) txtData; + +- (id) initWithDomain: (NSString *) domain + type: (NSString *) type + name: (NSString *) name; +- (id) initWithDomain: (NSString *) domain + type: (NSString *) type + name: (NSString *) name + port: (int) port; + +- (void) removeFromRunLoop: (NSRunLoop *) aRunLoop + forMode: (NSString *) mode; +- (void) scheduleInRunLoop: (NSRunLoop *) aRunLoop + forMode: (NSString *) mode; + +- (void) publish; +- (void) resolve; +- (void) resolveWithTimeout: (NSTimeInterval) timeout; +- (void) stop; + +- (void) startMonitoring; +- (void) stopMonitoring; + +- (id) delegate; +- (void) setDelegate: (id) delegate; + +- (NSArray *) addresses; +- (NSString *) domain; +- (NSString *) hostName; +- (NSString *) name; +- (NSString *) type; + +- (NSString *) protocolSpecificInformation; +- (void) setProtocolSpecificInformation: (NSString *) specificInformation; + +- (NSData *) TXTRecordData; +- (BOOL) setTXTRecordData: (NSData *) recordData; + +- (BOOL) getInputStream: (NSInputStream **) inputStream + outputStream: (NSOutputStream **) outputStream; + +@end + +/** + * + * + * NSNetServiceBrowser class description + * + *

+ * + *

+ * + *

+ * + *

+ *
+ *

+ * [NSNetServiceBrowser] asynchronously lets you discover network domains + * and, additionally, search for a type of network service. It sends its + * delegate a message whenever it discovers a new network service, and + * whenever a network service goes away. + *

+ *

+ * Each [NSNetServiceBrowser] performs one search at a time. So in order + * to perform multiple searches simultaneously, create multiple instances. + *

+ */ + +@interface NSNetServiceBrowser : NSObject +{ + @private + void * _netServiceBrowser; + id _delegate; + void * _reserved; +} + +- (id) init; + +- (void) removeFromRunLoop: (NSRunLoop *) aRunLoop + forMode: (NSString *) mode; +- (void) scheduleInRunLoop: (NSRunLoop *) aRunLoop + forMode: (NSString *) mode; + +- (void) searchForAllDomains; +- (void) searchForBrowsableDomains; +- (void) searchForRegistrationDomains; + +- (void) searchForServicesOfType: (NSString *) serviceType + inDomain: (NSString *) domainName; + +- (void) stop; + +- (id) delegate; +- (void) setDelegate: (id) delegate; + +@end + +/** + * + * + * NSObject (NSNetServiceDelegateMethods) class description + * + *

+ * + *

+ * + *

+ * + *

+ *
+ *

+ * This informal protocol must be adopted by any class wishing to implement + * an [NSNetService] delegate. + *

+ */ + +@interface NSObject (NSNetServiceDelegateMethods) + +/** + * Notifies the delegate that the network is ready to publish the service. + * + *

See also:
+ * [NSNetService-publish]
+ *

+ */ + +- (void) netServiceWillPublish: (NSNetService *) sender; + +/** + * Notifies the delegate that the service was successfully published. + * + *

See also:
+ * [NSNetService-publish]
+ *

+ */ + +- (void) netServiceDidPublish: (NSNetService *) sender; + +/** + * Notifies the delegate that the service could not get published. + * + *

See also:
+ * [NSNetService-publish]
+ *

+ */ + +- (void) netService: (NSNetService *) sender + didNotPublish: (NSDictionary *) errorDict; + +/** + * Notifies the delegate that the network is ready to resolve the service. + * + *

See also:
+ * [NSNetService-resolveWithTimeout:]
+ *

+ */ + +- (void) netServiceWillResolve: (NSNetService *) sender; + +/** + * Notifies the delegate that the service was resolved. + * + *

See also:
+ * [NSNetService-resolveWithTimeout:]
+ *

+ */ + +- (void) netServiceDidResolveAddress: (NSNetService *) sender; + +/** + * Notifies the delegate that the service could not get resolved. + * + *

See also:
+ * [NSNetService-resolveWithTimeout:]
+ *

+ */ + +- (void) netService: (NSNetService *) sender + didNotResolve: (NSDictionary *) errorDict; + +/** + * Notifies the delegate that the request was stopped. + * + *

See also:
+ * [NSNetService-stop]
+ *

+ */ + +- (void) netServiceDidStop: (NSNetService *) sender; + +/** + * Notifies the delegate that the TXT record has been updated. + * + *

See also:
+ * [NSNetService-startMonitoring]
+ * [NSNetService-stopMonitoring] + *

+ */ + +- (void) netService: (NSNetService *) sender + didUpdateTXTRecordData: (NSData *) data; + +@end + +/** + * + * + * NSObject (NSNetServiceBrowserDelegateMethods) class description + * + *

+ * + *

+ * + *

+ * + *

+ *
+ *

+ * This informal protocol must be adopted by any class wishing to implement + * an [NSNetServiceBrowser] delegate. + *

+ */ + +@interface NSObject (NSNetServiceBrowserDelegateMethods) + +/** + * Notifies the delegate that the search is about to begin. + * + *

See also:
+ * [NSNetServiceBrowser-netServiceBrowser:didNotSearch:]
+ *

+ */ + +- (void) netServiceBrowserWillSearch: (NSNetServiceBrowser *)aNetServiceBrowser; + +/** + * Notifies the delegate that the search was unsuccessful. + * + *

See also:
+ * [NSNetServiceBrowser-netServiceBrowserWillSearch:]
+ *

+ */ + +- (void) netServiceBrowser: (NSNetServiceBrowser *) aNetServiceBrowser + didNotSearch: (NSDictionary *) errorDict; + +/** + * Notifies the delegate that the search was stopped. + * + *

See also:
+ * [NSNetServiceBrowser-stop]
+ *

+ */ + +- (void) netServiceBrowserDidStopSearch: + (NSNetServiceBrowser *)aNetServiceBrowser; + +/** + * Notifies the delegate that a domain was found. + * + *

See also:
+ * [NSNetServiceBrowser-searchForBrowsableDomains]
+ * [NSNetServiceBrowser-searchForRegistrationDomains]
+ *

+ */ + +- (void) netServiceBrowser: (NSNetServiceBrowser *) aNetServiceBrowser + didFindDomain: (NSString *) domainString + moreComing: (BOOL) moreComing; + +/** + * Notifies the delegate that a domain has become unavailable. + * + *

See also:
+ *
+ *

+ */ + +- (void) netServiceBrowser: (NSNetServiceBrowser *) aNetServiceBrowser + didRemoveDomain: (NSString *) domainString + moreComing: (BOOL) moreComing; + +/** + * Notifies the delegate that a service was found. + * + *

See also:
+ * [NSNetServiceBrowser-searchForServicesOfType:inDomain:]
+ *

+ */ + +- (void) netServiceBrowser: (NSNetServiceBrowser *) aNetServiceBrowser + didFindService: (NSNetService *) aNetService + moreComing: (BOOL) moreComing; + +/** + * Notifies the delegate that a service has become unavailable. + * + *

See also:
+ *
+ *

+ */ + +- (void) netServiceBrowser: (NSNetServiceBrowser *) aNetServiceBrowser + didRemoveService: (NSNetService *) aNetService + moreComing: (BOOL) moreComing; + +@end + +#endif /* __NSNetServices_h_GNUSTEP_BASE_INCLUDE */ + diff --git a/Headers/Foundation/NSNotification.h b/Headers/Foundation/NSNotification.h index 736b934c0..698f87f69 100644 --- a/Headers/Foundation/NSNotification.h +++ b/Headers/Foundation/NSNotification.h @@ -19,8 +19,8 @@ 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., 51 Franklin Street, Fifth Floor, Boston, - MA 02111 USA. + Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02111 USA. AutogsdocSource: NSNotification.m AutogsdocSource: NSNotificationCenter.m @@ -28,9 +28,14 @@ #ifndef __NSNotification_h_GNUSTEP_BASE_INCLUDE #define __NSNotification_h_GNUSTEP_BASE_INCLUDE +#import -#include -#include +#import +#import + +#if defined(__cplusplus) +extern "C" { +#endif @class NSString; @class NSDictionary; @@ -84,16 +89,8 @@ @end -#ifndef NO_GNUSTEP - -@interface NSNotificationCenter (GNUstep) -/** - * You can disable locking in a multi-threaded program if you KNOW that only - * one thread will ever use the notification center.
- * DEPRECATED - */ -- (BOOL) setLockingDisabled: (BOOL)flag; -@end +#if defined(__cplusplus) +} #endif #endif /*__NSNotification_h_GNUSTEP_BASE_INCLUDE */ diff --git a/Headers/Foundation/NSNotificationQueue.h b/Headers/Foundation/NSNotificationQueue.h index 457eba1fc..3890bb8dd 100644 --- a/Headers/Foundation/NSNotificationQueue.h +++ b/Headers/Foundation/NSNotificationQueue.h @@ -44,12 +44,19 @@ Boston, MA 02111 USA. */ -#ifndef __NSNotificationQueue_h__ -#define __NSNotificationQueue_h__ +#ifndef __NSNotificationQueue_h_GNUSTEP_BASE_INCLUDE +#define __NSNotificationQueue_h_GNUSTEP_BASE_INCLUDE +#import -#include +#import -@class NSMutableArray; +#if defined(__cplusplus) +extern "C" { +#endif + +@class NSArray; +@class NSNotification; +@class NSNotificationCenter; /* * Posting styles into notification queue @@ -67,9 +74,9 @@ */ typedef enum { - NSPostWhenIdle, - NSPostASAP, - NSPostNow + NSPostWhenIdle = 1, + NSPostASAP = 2, + NSPostNow = 3 } NSPostingStyle; /** @@ -84,9 +91,9 @@ typedef enum { */ typedef enum { - NSNotificationNoCoalescing = 0, - NSNotificationCoalescingOnName = 1, - NSNotificationCoalescingOnSender = 2, + NSNotificationNoCoalescing = 0, + NSNotificationCoalescingOnName = 1, + NSNotificationCoalescingOnSender = 2, } NSNotificationCoalescing; /* @@ -126,4 +133,8 @@ struct _NSNotificationQueueList; @end -#endif /* __NSNotificationQueue_h__ */ +#if defined(__cplusplus) +} +#endif + +#endif /* __NSNotificationQueue_h_GNUSTEP_BASE_INCLUDE */ diff --git a/Headers/Foundation/NSNull.h b/Headers/Foundation/NSNull.h index 5d62f1f3c..b84b6dbef 100644 --- a/Headers/Foundation/NSNull.h +++ b/Headers/Foundation/NSNull.h @@ -18,23 +18,33 @@ 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., 51 Franklin Street, Fifth Floor, Boston, - MA 02111 USA. + Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02111 USA. */ #ifndef __NSNull_h_GNUSTEP_BASE_INCLUDE #define __NSNull_h_GNUSTEP_BASE_INCLUDE +#import + +#if OS_API_VERSION(GS_API_MACOSX, GS_API_LATEST) + +#import + +#if defined(__cplusplus) +extern "C" { +#endif /* * An object to use as a placeholder - in collections for instance. */ -#ifndef NO_MACOS_X -#include - @interface NSNull : NSObject + (NSNull*) null; @end +#if defined(__cplusplus) +} #endif -#endif /* __NSNull_h_GNUSTEP_BASE_INCLUDE */ +#endif /* GS_API_MACOSX */ + +#endif /* __NSNull_h_GNUSTEP_BASE_INCLUDE */ diff --git a/Headers/Foundation/NSNumberFormatter.h b/Headers/Foundation/NSNumberFormatter.h index 3e6a525e8..5840330e5 100644 --- a/Headers/Foundation/NSNumberFormatter.h +++ b/Headers/Foundation/NSNumberFormatter.h @@ -19,18 +19,23 @@ 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., 51 Franklin Street, Fifth Floor, Boston, - MA 02111 USA. + Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02111 USA. */ -#ifndef _NSNumberFormatter_h__ -#define _NSNumberFormatter_h__ +#ifndef _NSNumberFormatter_h_GNUSTEP_BASE_INCLUDE +#define _NSNumberFormatter_h_GNUSTEP_BASE_INCLUDE +#import -#ifndef STRICT_OPENSTEP +#if OS_API_VERSION(GS_API_MACOSX, GS_API_LATEST) -#include -#include -#include +#import +#import +#import + +#if defined(__cplusplus) +extern "C" { +#endif @class NSString, NSAttributedString, NSDictionary; @@ -295,5 +300,11 @@ @end +#if defined(__cplusplus) +} #endif -#endif + +#endif /* GS_API_MACOSX */ + +#endif /* _NSNumberFormatter_h_GNUSTEP_BASE_INCLUDE */ + diff --git a/Headers/Foundation/NSObjCRuntime.h b/Headers/Foundation/NSObjCRuntime.h index 31800cb78..9980cc08f 100644 --- a/Headers/Foundation/NSObjCRuntime.h +++ b/Headers/Foundation/NSObjCRuntime.h @@ -18,8 +18,8 @@ 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., 51 Franklin Street, Fifth Floor, Boston, - MA 02111 USA. + Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02111 USA. AutogsdocSource: NSObjCRuntime.m AutogsdocSource: NSLog.m @@ -28,8 +28,13 @@ #ifndef __NSObjCRuntime_h_GNUSTEP_BASE_INCLUDE #define __NSObjCRuntime_h_GNUSTEP_BASE_INCLUDE +#import -#include +#import + +#if defined(__cplusplus) +extern "C" { +#endif GS_EXPORT NSString *NSStringFromSelector(SEL aSelector); GS_EXPORT SEL NSSelectorFromString(NSString *aSelectorName); @@ -38,7 +43,7 @@ GS_EXPORT NSString *NSStringFromClass(Class aClass); GS_EXPORT const char *NSGetSizeAndAlignment(const char *typePtr, unsigned int *sizep, unsigned int *alignp); -#ifndef NO_GNUSTEP +#if OS_API_VERSION(GS_API_NONE, GS_API_NONE) /* Logging */ /** * OpenStep spec states that log messages go to stderr, but just in case @@ -65,4 +70,8 @@ GS_EXPORT void NSLogv (NSString *format, va_list args); #define nil 0 #endif +#if defined(__cplusplus) +} +#endif + #endif /* __NSObjCRuntime_h_GNUSTEP_BASE_INCLUDE */ diff --git a/Headers/Foundation/NSObject.h b/Headers/Foundation/NSObject.h index 2954db6a8..23e055fe0 100644 --- a/Headers/Foundation/NSObject.h +++ b/Headers/Foundation/NSObject.h @@ -18,8 +18,8 @@ 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., 51 Franklin Street, Fifth Floor, Boston, - MA 02111 USA. + Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02111 USA. AutogsdocSource: NSObject.m AutogsdocSource: Additions/GSCategories.m @@ -27,141 +27,18 @@ #ifndef __NSObject_h_GNUSTEP_BASE_INCLUDE #define __NSObject_h_GNUSTEP_BASE_INCLUDE +#import -/* - * Check consistency of definitions for system compatibility. - */ -#if defined(STRICT_OPENSTEP) -#define OS_API_VERSION 10000 -#define NO_GNUSTEP 1 -#elif defined(STRICT_MACOS_X) -#define OS_API_VERSION 100000 -#define NO_GNUSTEP 1 -#else -#undef NO_GNUSTEP -#endif - -/* - * NB. The version values below must be integers ... by convention these are - * made up of two digits each for major, minor and subminor version numbers - * (ie each is in the range 00 to 99 though a leading zero in the major - * number is not permitted). - * So for a MacOS-X 10.3.9 release the version number would be 100309 - * - * You may define GS_GNUSTEP_V or GS_OPENSTEP_V to ensure that your - * program only 'sees' the specified varsion of the API. - */ - -/** - *

Macro to check a defined GNUstep version number (GS_GNUSTEP_V) against - * the supplied arguments. Returns true if no GNUstep version is specified, - * or if ADD <= version < REM, where ADD is the version - * number at which a feature guarded by the macro was introduced and - * REM is the version number at which it was removed. - *

- *

The version number arguments are six digit integers where the first - * two digits are the major version number, the second two are the minor - * version number and the last two are the subminor number (all left padded - * with a zero where necessary). However, for convenience you can also - * use any of several predefined constants ... - * GS_API_NONE, - * GS_API_LATEST, - * GS_API_OSSPEC, - * GS_API_OPENSTEP, - * GS_API_MACOSX - *

- *

Also see OS_API_VERSION - *

- *

NB. If you are changing the API (eg adding a new feature) you need - * to control the visibility io the new header file code using
- * #if GS_API_VERSION(ADD,GS_API_LATEST)
- * where ADD is the version number of the next minor - * release after the most recent one.
- * As a general principle you should not change the API with - * changing subminor version numbers ... as that tends to confuse - * people (though Apple has sometimes done it). - *

- */ -#define GS_API_VERSION(ADD,REM) \ - (!defined(GS_GNUSTEP_V) || (GS_GNUSTEP_V >= ADD && GS_GNUSTEP_V < REM)) - -/** - *

Macro to check a defined OpenStep/OPENSTEP/MacOS-X version against the - * supplied arguments. Returns true if no version is specified, or if - * ADD <= version < REM, where ADD is the version - * number at which a feature guarded by the macro was introduced and - * REM is the version number at which it was removed. - *

- *

The version number arguments are six digit integers where the first - * two digits are the major version number, the second two are the minor - * version number and the last two are the subminor number (all left padded - * with a zero where necessary). However, for convenience you can also - * use any of several predefined constants ... - * GS_API_NONE, - * GS_API_LATEST, - * GS_API_OSSPEC, - * GS_API_OPENSTEP, - * GS_API_MACOSX - *

- *

Also see GS_API_VERSION - *

- */ -#define OS_API_VERSION(ADD,REM) \ - (!defined(GS_OPENSTEP_V) || (GS_OPENSTEP_V >= ADD && GS_OPENSTEP_V < REM)) - -/** - * A constant to represent a feature which is not present in any version. - * Use this to say a feature is not present in an API.
- * eg.
- * #if OS_API_VERSION - * (GS_API_NONE, GS_API_NONE)
- * denotes code not present in OpenStep/OPENSTEP/MacOS-X - */ -#define GS_API_NONE 0 - -/** - * A constant to represent a feature which is still present in the latest - * version. This is the highest possible version number.
- * eg.
- * #if OS_API_VERSION - * (GS_API_MACOSX, GS_API_LATEST)
- * denotes code present from the initial MacOS-X version onwards. - */ -#define GS_API_LATEST 999999 - -/** - * The version number of the initial OpenStep specification.
- * eg.
- * #if OS_API_VERSION - * (GS_API_OSSPEC, GS_API_LATEST)
- * denotes code present from the OpenStep specification onwards. - */ -#define GS_API_OSSPEC 10000 - -/** - * The version number of the first OPENSTEP implementation.
- * eg.
- * #if OS_API_VERSION - * (GS_API_OPENSTEP, GS_API_LATEST)
- * denotes code present from the initial OPENSTEP version onwards. - */ -#define GS_API_OPENSTEP 40000 - -/** - * The version number of the first MacOS-X implementation.
- * eg.
- * #if OS_API_VERSION - * (GS_API_MACOSX, GS_API_LATEST)
- * denotes code present from the initial MacOS-X version onwards. - */ -#define GS_API_MACOSX 100000 - -#include -#include -#include +#import +#import +#include #include #include -#include +#import + +#if defined(__cplusplus) +extern "C" { +#endif @class NSArchiver; @class NSArray; @@ -291,13 +168,13 @@ Class isa; } -#ifndef NO_GNUSTEP +#if OS_API_VERSION(GS_API_NONE, GS_API_NONE) #if GS_WITH_GC + (BOOL) requiresTypedMemory; #endif #endif -#ifndef STRICT_OPENSTEP +#if OS_API_VERSION(GS_API_MACOSX, GS_API_LATEST) - (NSString*) className; #endif @@ -412,7 +289,7 @@ NSComparisonResult; enum {NSNotFound = 0x7fffffff}; -#ifndef NO_GNUSTEP +#if OS_API_VERSION(GS_API_NONE, GS_API_NONE) @interface NSObject (NEXTSTEP) - error:(const char *)aString, ...; @@ -494,7 +371,7 @@ GS_EXPORT NSRecursiveLock *gnustep_global_lock; - (void) gcFinalize; @end -#include +#import /** * Declares some methods for sending messages to self after a fixed delay. * (These methods are in OpenStep and OS X.) @@ -719,4 +596,8 @@ if (__value != __object) \ #endif +#if defined(__cplusplus) +} +#endif + #endif /* __NSObject_h_GNUSTEP_BASE_INCLUDE */ diff --git a/Headers/Foundation/NSPathUtilities.h b/Headers/Foundation/NSPathUtilities.h index 9bcd0ce1d..8adc1e9f4 100644 --- a/Headers/Foundation/NSPathUtilities.h +++ b/Headers/Foundation/NSPathUtilities.h @@ -26,12 +26,20 @@ #ifndef __NSPathUtilities_h_GNUSTEP_BASE_INCLUDE #define __NSPathUtilities_h_GNUSTEP_BASE_INCLUDE +#import -#include +#import + +#if defined(__cplusplus) +extern "C" { +#endif -#ifndef NO_GNUSTEP @class NSDictionary; @class NSMutableDictionary; +@class NSString; + +#if OS_API_VERSION(GS_API_NONE, GS_API_NONE) + /** * This extension permits a change of username from that specified in the * LOGNAME environment variable. Using it will almost certainly cause @@ -98,12 +106,14 @@ GS_EXPORT NSString *NSUserName(void); GS_EXPORT NSString *NSHomeDirectory(void); GS_EXPORT NSString *NSHomeDirectoryForUser(NSString *loginName); -#ifndef STRICT_OPENSTEP +#if OS_API_VERSION(GS_API_MACOSX, GS_API_LATEST) /** * Enumeration of possible requested directory type specifiers for - * NSSearchPathForDirectoriesInDomains() function. These correspond to the - * subdirectories that may be found under, e.g., $GNUSTEP_SYSTEM_ROOT, such - * as "Library" and "Applications". + * NSSearchPathForDirectoriesInDomains() function. On a traditional + * GNUstep filesystem layout these correspond to the subdirectories + * that may be found in the various domains, such as "Library" + * and "Applications". In a different filesystem layout these + * directories might be located anywhere on disk. { NSApplicationDirectory, @@ -114,42 +124,57 @@ GS_EXPORT NSString *NSHomeDirectoryForUser(NSString *loginName); NSDeveloperDirectory, NSUserDirectory, NSDocumentationDirectory, + NSDocumentDirectory, + NSCoreServiceDirectory, + NSDesktopDirectory, + NSCachesDirectory, + NSApplicationSupportDirectory NSAllApplicationsDirectory, NSAllLibrariesDirectory, GSLibrariesDirectory, GSToolsDirectory, - GSApplicationSupportDirectory + GSAdminToolsDirectory, + GSFontsDirectory, + GSFrameworksDirectory, + GSWebApplicationsDirectory } */ typedef enum { - NSApplicationDirectory, - NSDemoApplicationDirectory, - NSDeveloperApplicationDirectory, - NSAdminApplicationDirectory, - NSLibraryDirectory, - NSDeveloperDirectory, - NSUserDirectory, - NSDocumentationDirectory, - -/* Apple Reserved Directory Identifiers */ + NSApplicationDirectory = 1, /** Applications */ + NSDemoApplicationDirectory, /** Demos */ + NSDeveloperApplicationDirectory, /** Developer/Applications */ + NSAdminApplicationDirectory, /** Administration */ + NSLibraryDirectory, /** Library */ + NSDeveloperDirectory, /** Developer */ + NSUserDirectory, /** user home directories */ + NSDocumentationDirectory, /** Documentation */ +#if OS_API_VERSION(100200, GS_API_LATEST) + NSDocumentDirectory, /** Documents */ +#endif +#if OS_API_VERSION(100300, GS_API_LATEST) + NSCoreServicesDirectory, /** CoreServices */ +#endif +#if OS_API_VERSION(100400, GS_API_LATEST) + NSDesktopDirectory = 12, /** location of users desktop */ + NSCachesDirectory = 13, /** location of users cache files */ + NSApplicationSupportDirectory = 14, /** location of app support files */ +#endif - NSAllApplicationsDirectory, - NSAllLibrariesDirectory, + NSAllApplicationsDirectory = 100, /** all app directories */ + NSAllLibrariesDirectory = 101, /** all library resources */ -/* GNUstep Directory Identifiers */ - - //GSApplicationSupportDirectory = 150, - //GSFontsDirectory, - //GSFrameworksDirectory, - GSLibrariesDirectory, - GSToolsDirectory, - GSApplicationSupportDirectory, - GSPreferencesDirectory, - - GSFontsDirectory, - GSFrameworksDirectory +#define GSApplicationSupportDirectory NSApplicationSupportDirectory +/* GNUstep Directory Identifiers + * Start at 1000, we hope Apple will never overlap. + */ + GSLibrariesDirectory = 1000, /** libraries (binary code) */ + GSToolsDirectory, /** non-gui programs */ + GSFontsDirectory, /** font storage */ + GSFrameworksDirectory, /** frameworks */ + GSWebApplicationsDirectory, /** web applications (GSWeb or SOPE) */ + GSAdminToolsDirectory /** admin non-gui programs */ } NSSearchPathDirectory; /** @@ -159,19 +184,72 @@ typedef enum */ typedef enum { - NSUserDomainMask = 1, - NSLocalDomainMask = 2, - NSNetworkDomainMask = 4, - NSSystemDomainMask = 8, - NSAllDomainsMask = 0xffffffff, + NSUserDomainMask = 1, /** The user's personal items */ + NSLocalDomainMask = 2, /** Local for all users on the machine */ + NSNetworkDomainMask = 4, /** Public for all users on network */ + NSSystemDomainMask = 8, /** Standard GNUstep items */ + NSAllDomainsMask = 0x0ffff, /** all domains */ } NSSearchPathDomainMask; +/** + * Returns an array of search paths to look at for resources.
+ * The paths are returned in domain order: + * USER, LOCAL, NETWORK then SYSTEM.
+ * The presence of a path in this list does not mean that the + * path actually exists in the filesystem.
+ * If you are wanting to locate an existing resource, you should normally + * call this function with NSAllDomainsMask, but if you wish to find the + * path in which you should create a new file, you would generally + * specify a particular domain, and then create the path in the file + * system if it does not already exist. + */ GS_EXPORT NSArray *NSSearchPathForDirectoriesInDomains(NSSearchPathDirectory directoryKey, NSSearchPathDomainMask domainMask, BOOL expandTilde); + +/** + * Returns the full username of the current user. + * If unable to determine this, returns the standard user name. + */ GS_EXPORT NSString *NSFullUserName(void); + +/** + * Returns the standard paths in which applications are stored and + * should be searched for. Calls NSSearchPathForDirectoriesInDomains()
+ * Refer to the GNUstep File System Hierarchy documentation for more info. + */ GS_EXPORT NSArray *NSStandardApplicationPaths(void); + +/** + * Returns the standard paths in which resources are stored and + * should be searched for. Calls NSSearchPathForDirectoriesInDomains()
+ * Refer to the GNUstep File System Hierarchy documentation for more info. + */ GS_EXPORT NSArray *NSStandardLibraryPaths(void); + +/** + * Returns the name of a directory in which temporary files can be stored. + * Under GNUstep this is a location which is not readable by other users. + *
+ * If a suitable directory can't be found or created, this function raises an + * NSGenericException. + */ GS_EXPORT NSString *NSTemporaryDirectory(void); + +/** + * Returns the location of the root directory of the file + * hierarchy. This lets you build paths in a system independent manner + * (for instance the root on unix is '/' but on windows it is 'C:\') + * by appending path components to the root.
+ * Don't assume that /System, /Network etc exist in this path (generally + * they don't)! Use other path utility functions such as + * NSSearchPathForDirectoriesInDomains() to find standard locations + * for libraries, applications etc.
+ * Refer to the GNUstep File System Hierarchy documentation for more info. + */ GS_EXPORT NSString *NSOpenStepRootDirectory(void); -#endif /* !STRICT_OPENSTEP */ +#endif /* GS_API_MACOSX */ + +#if defined(__cplusplus) +} +#endif #endif /* __NSPathUtilities_h_GNUSTEP_BASE_INCLUDE */ diff --git a/Headers/Foundation/NSPort.h b/Headers/Foundation/NSPort.h index e1c7ccecc..8a8dfe557 100644 --- a/Headers/Foundation/NSPort.h +++ b/Headers/Foundation/NSPort.h @@ -18,8 +18,8 @@ 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., 51 Franklin Street, Fifth Floor, Boston, - MA 02111 USA. + Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02111 USA. AutogsdocSource: NSPort.m AutogsdocSource: NSSocketPort.m @@ -28,9 +28,10 @@ #ifndef __NSPort_h_GNUSTEP_BASE_INCLUDE #define __NSPort_h_GNUSTEP_BASE_INCLUDE +#import -#include -#include +#import +#import #if defined(__MINGW32__) #include @@ -40,6 +41,10 @@ #define SOCKET int #endif +#if defined(__cplusplus) +extern "C" { +#endif + @class NSMutableArray; @class NSConnection; @class NSDate; @@ -133,7 +138,7 @@ GS_EXPORT NSString * const NSPortTimeoutException; /* OPENSTEP */ */ - (BOOL) isValid; -#ifndef STRICT_OPENSTEP +#if OS_API_VERSION(GS_API_MACOSX, GS_API_LATEST) /** * Adds to run loop as input source to be notified for input in given mode. * This method is for use by subclasses. @@ -183,7 +188,7 @@ GS_EXPORT NSString* const NSPortDidBecomeInvalidNotification; #define PortBecameInvalidNotification NSPortDidBecomeInvalidNotification -#ifndef STRICT_OPENSTEP +#if OS_API_VERSION(GS_API_MACOSX, GS_API_LATEST) /** * Native socket type. @@ -312,6 +317,10 @@ typedef SOCKET NSSocketNativeHandle; #endif +#if defined(__cplusplus) +} +#endif + #endif /* __NSPort_h_GNUSTEP_BASE_INCLUDE */ diff --git a/Headers/Foundation/NSPortCoder.h b/Headers/Foundation/NSPortCoder.h index f450ca6fd..356a09cec 100644 --- a/Headers/Foundation/NSPortCoder.h +++ b/Headers/Foundation/NSPortCoder.h @@ -18,14 +18,19 @@ 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., 51 Franklin Street, Fifth Floor, Boston, - MA 02111 USA. + Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02111 USA. */ -#ifndef __NSPortCoder_h -#define __NSPortCoder_h +#ifndef __NSPortCoder_h_GNUSTEP_BASE_INCLUDE +#define __NSPortCoder_h_GNUSTEP_BASE_INCLUDE +#import -#include +#import + +#if defined(__cplusplus) +extern "C" { +#endif @class NSMutableArray; @class NSMutableDictionary; @@ -173,4 +178,9 @@ @end -#endif /* __NSPortCoder_h */ +#if defined(__cplusplus) +} +#endif + +#endif /* __NSPortCoder_h_GNUSTEP_BASE_INCLUDE */ + diff --git a/Headers/Foundation/NSPortMessage.h b/Headers/Foundation/NSPortMessage.h index 59648156e..1f9b89485 100644 --- a/Headers/Foundation/NSPortMessage.h +++ b/Headers/Foundation/NSPortMessage.h @@ -18,15 +18,20 @@ 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., 51 Franklin Street, Fifth Floor, Boston, - MA 02111 USA. + Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02111 USA. */ #ifndef __NSPortMessage_h_GNUSTEP_BASE_INCLUDE #define __NSPortMessage_h_GNUSTEP_BASE_INCLUDE +#import -#include -#include +#import +#import + +#if defined(__cplusplus) +extern "C" { +#endif /** *

The data transported for distributed objects communications is sent over @@ -100,5 +105,9 @@ - (unsigned) msgid; @end +#if defined(__cplusplus) +} +#endif + #endif diff --git a/Headers/Foundation/NSPortNameServer.h b/Headers/Foundation/NSPortNameServer.h index ac4d8d55c..0c06390a7 100644 --- a/Headers/Foundation/NSPortNameServer.h +++ b/Headers/Foundation/NSPortNameServer.h @@ -18,8 +18,8 @@ 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., 51 Franklin Street, Fifth Floor, Boston, - MA 02111 USA. + Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02111 USA. NSPortNameServer class reference @@ -31,9 +31,16 @@ #ifndef __NSPortNameServer_h_GNUSTEP_BASE_INCLUDE #define __NSPortNameServer_h_GNUSTEP_BASE_INCLUDE +#import -#include -#include +#import +#import + +#if OS_API_VERSION(GS_API_MACOSX,HS_API_LATEST) + +#if defined(__cplusplus) +extern "C" { +#endif @class NSPort, NSString, NSMutableArray; @@ -65,7 +72,25 @@ @interface NSMessagePortNameServer : NSPortNameServer + (id) sharedInstance; + +/** Returns the [NSMessagePort] instance registered for the specified name + * if it exists on the local host. + */ +- (NSPort*) portForName: (NSString*)name; + +/** Returns the port registered for the specified name (if it exists).
+ * The host must be an empty string or nil, since [NSMessagePort] instances + * on other hosts are inaccessible from the current host. + */ +- (NSPort*) portForName: (NSString*)name + onHost: (NSString*)host; @end +#if defined(__cplusplus) +} +#endif + +#endif + #endif diff --git a/Headers/Foundation/NSPredicate.h b/Headers/Foundation/NSPredicate.h index 288ae2367..66b57a5dd 100644 --- a/Headers/Foundation/NSPredicate.h +++ b/Headers/Foundation/NSPredicate.h @@ -24,9 +24,16 @@ #ifndef __NSPredicate_h_GNUSTEP_BASE_INCLUDE #define __NSPredicate_h_GNUSTEP_BASE_INCLUDE +#import -#include -#include +#if OS_API_VERSION(100400, GS_API_LATEST) + +#import +#import + +#if defined(__cplusplus) +extern "C" { +#endif @interface NSPredicate : NSObject @@ -47,4 +54,9 @@ - (NSArray *) filteredArrayUsingPredicate: (NSPredicate *)predicate; @end -#endif /* __NSPredicate_h_GNUSTEP_BASE_INCLUDE */ +#if defined(__cplusplus) +} +#endif + +#endif /* 100400 */ +#endif /* __NSPredicate_h_GNUSTEP_BASE_INCLUDE */ diff --git a/Headers/Foundation/NSProcessInfo.h b/Headers/Foundation/NSProcessInfo.h index 5ddcf8abd..8549134bc 100644 --- a/Headers/Foundation/NSProcessInfo.h +++ b/Headers/Foundation/NSProcessInfo.h @@ -20,14 +20,19 @@ 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., 51 Franklin Street, Fifth Floor, Boston, - MA 02111 USA. + Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02111 USA. */ #ifndef __NSProcessInfo_h_GNUSTEP_BASE_INCLUDE #define __NSProcessInfo_h_GNUSTEP_BASE_INCLUDE +#import -#include +#import + +#if defined(__cplusplus) +extern "C" { +#endif @class NSArray; @class NSMutableArray; @@ -35,12 +40,14 @@ @class NSData; @class NSMutableSet; -#ifndef STRICT_OPENSTEP -/* - * Constants returned by -operatingSystem +#if OS_API_VERSION(GS_API_MACOSX,GS_API_LATEST) + +/** + * Constants returned by the -operatingSystem method. * NB. The presence of a constant in this list does *NOT* imply that * the named operating system is supported. Some values are provided - * for MacOS-X compatibility only. + * for MacOS-X compatibility or are obsolete and provided for + * backward compatibility. */ enum { NSWindowsNTOperatingSystem = 1, @@ -50,51 +57,203 @@ enum { NSMACHOperatingSystem, NSSunOSOperatingSystem, NSOSF1OperatingSystem, - NSGNULinuxOperatingSystem = 100, - NSBSDOperatingSystem, - NSBeOperatingSystem, - NSCygwinOperatingSystem +#if OS_API_VERSION(GS_API_NONE,GS_API_NONE) + GSGNULinuxOperatingSystem = 100, + GSBSDOperatingSystem, + GSBeOperatingSystem, + GSCygwinOperatingSystem + +#if GS_API_VERSION(0,011500) +// Defines of deprecated constants for backward compatibility +#define NSGNULinuxOperatingSystem GSGNULinuxOperatingSystem +#define NSBSDOperatingSystem GSBSDOperatingSystem +#define NSBeOperatingSystem GSBeOperatingSystem +#define NSCygwinOperatingSystem GSCygwinOperatingSystem +#endif /* GS_API_VERSION(0,011500) */ + +#endif /* OS_API_VERSION(GS_API_NONE,GS_API_NONE) */ }; -#endif +#endif /* OS_API_VERSION(GS_API_MACOSX,GS_API_LATEST) */ @interface NSProcessInfo: NSObject +/** + * Returns the shared NSProcessInfo object for the current process. + */ + (NSProcessInfo*) processInfo; +/** + * Returns an array containing the arguments supplied to start this + * process.
+ * NB. In GNUstep, any arguments of the form --GNU-Debug=... + * are not included in this array ... they are part of the + * debug mechanism, and are hidden so that setting debug variables + * will not effect the normal operation of the program.
+ * Please note, the special --GNU-Debug=... syntax differs from + * that which is used to specify values for the [NSUserDefaults] system.
+ * User defaults are set on the command line by specifying the default name + * (with a leading hyphen) as one argument, and the default value as the + * following argument. The arguments used to set user defaults are + * present in the array returned by this method. + */ - (NSArray*) arguments; + +/** + * Returns a dictionary giving the environment variables which were + * provided for the process to use. + */ - (NSDictionary*) environment; + +/** + * Returns a string which may be used as a globally unique identifier.
+ * The string contains the host name, the process ID, a timestamp and a + * counter.
+ * The first three values identify the process in which the string is + * generated, while the fourth ensures that multiple strings generated + * within the same process are unique. + */ - (NSString*) globallyUniqueString; + +/** + * Returns the name of the machine on which this process is running. + */ - (NSString*) hostName; -#ifndef STRICT_OPENSTEP + +#if OS_API_VERSION(GS_API_MACOSX,GS_API_LATEST) + +/** + * Return a number representing the operating system type.
+ * The known types are listed in the header file, but not all of the + * listed types are actually implemented ... some are present for + * MacOS-X compatibility only.
+ * + * NSWindowsNTOperatingSystem - used for Windows NT, and later + * NSWindows95OperatingSystem - probably never to be implemented + * NSSolarisOperatingSystem - used for Sun Solaris + * NSHPUXOperatingSystem - used for HP/UX + * NSMACHOperatingSystem - MacOSX and perhaps Hurd in future? + * NSSunOSOperatingSystem - Used for Sun Sun/OS + * NSOSF1OperatingSystem - Used for OSF/1 (probably obsolete) + * GSGNULinuxOperatingSystem - the GNUstep 'standard' + * GSBSDOperatingSystem - BSD derived operating systems + * GSBeperatingSystem - Used for Be-OS (probably obsolete) + * GSCygwinOperatingSystem - cygwin unix-like environment + * + */ - (unsigned int) operatingSystem; + +/** + * Return a human readable string representing the operating system type.
+ * The supported types are - + * + * NSWindowsNTOperatingSystem - used for Windows NT, and later + * NSWindows95OperatingSystem - probably never to be implemented + * NSSolarisOperatingSystem - used for Sun Solaris + * NSHPUXOperatingSystem - used for HP/UX + * NSMACHOperatingSystem - MacOSX and perhaps Hurd in future? + * NSSunOSOperatingSystem - Used for Sun Sun/OS + * NSOSF1OperatingSystem - Used for OSF/1 (probably obsolete) + * GSGNULinuxOperatingSystem - the GNUstep 'standard' + * GSBSDOperatingSystem - BSD derived operating systems + * GSBeperatingSystem - Used for Be-OS (probably obsolete) + * GSCygwinOperatingSystem - cygwin unix-like environment + * + */ - (NSString*) operatingSystemName; + +/** + * Returns a human readable version string for the current operating system + * version. + */ +#if OS_API_VERSION(100200,GS_API_LATEST) +- (NSString *) operatingSystemVersionString; +#endif + +/** + * Returns the process identifier number which uniquely identifies + * this process on this machine. + */ - (int) processIdentifier; #endif + +/** + * Returns the process name for this process. This may have been set using + * the -setProcessName: method, or may be the default process name (the + * file name of the binary being executed). + */ - (NSString*) processName; +/** + * Change the name of the current process to newName. + */ - (void) setProcessName: (NSString*)newName; @end -#ifndef NO_GNUSTEP +#if OS_API_VERSION(GS_API_NONE,GS_API_NONE) +/** + * Provides GNUstep-specific methods for controlled debug logging (a GNUstep + * facility) and an internal/developer-related method. + */ @interface NSProcessInfo (GNUstep) + +/** + * Returns a indication of whether debug logging is enabled. + * This returns YES unless a call to -setDebugLoggingEnabled: has + * been used to turn logging off. + */ - (BOOL) debugLoggingEnabled; + +/** + * This method returns a set of debug levels set using the + * --GNU-Debug=... command line option and/or the GNU-Debug + * user default.
+ * You can modify this set to change the debug logging under + * your programs control ... but such modifications are not + * thread-safe. + */ - (NSMutableSet*) debugSet; + +/** + * This method permits you to turn all debug logging on or off + * without modifying the set of debug levels in use. + */ - (void) setDebugLoggingEnabled: (BOOL)flag; + +/** + * Set the file to which NSLog output should be directed.
+ * Returns YES on success, NO on failure.
+ * By default logging goes to standard error. + */ - (BOOL) setLogFile: (NSString*)path; + +/** + * Fallback/override method. The developer must call this method to initialize + * the NSProcessInfo system if none of the system-specific hacks to + * auto-initialize it are working.
+ * It is also safe to call this method to override the effects + * of the automatic initialisation, which some applications may need + * to do when using GNUstep libraries embeddedm within other frameworks. + */ + (void) initializeWithArguments: (char**)argv count: (int)argc environment: (char**)env; @end -/* - * This function determines if the specified debug level is present in the - * set of active debug levels. +/** + * Function for rapid testing to see if a debug level is set.
+ * This is used by the debugging macros.
+ * If debug logging has been turned off, this returns NO even if + * the specified level exists in the set of debug levels. */ GS_EXPORT BOOL GSDebugSet(NSString *level); +#endif /* GS_API_NONE */ + +#if defined(__cplusplus) +} #endif #endif /* __NSProcessInfo_h_GNUSTEP_BASE_INCLUDE */ diff --git a/Headers/Foundation/NSPropertyList.h b/Headers/Foundation/NSPropertyList.h index e5ced15bd..a81ed99fc 100644 --- a/Headers/Foundation/NSPropertyList.h +++ b/Headers/Foundation/NSPropertyList.h @@ -18,8 +18,8 @@ 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., 51 Franklin Street, Fifth Floor, Boston, - MA 02111 USA. + Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02111 USA. AutogsdocSource: NSPropertyList.m @@ -27,10 +27,15 @@ #ifndef __NSPropertyList_h_GNUSTEP_BASE_INCLUDE #define __NSPropertyList_h_GNUSTEP_BASE_INCLUDE +#import -#ifndef STRICT_OPENSTEP +#import -#include +#if defined(__cplusplus) +extern "C" { +#endif + +#if OS_API_VERSION(GS_API_MACOSX, GS_API_LATEST) @class NSData, NSString; @@ -39,7 +44,7 @@ * deserialisation of a property list. */ typedef enum { - NSPropertyListImmutable, + NSPropertyListImmutable = 0, /** NSPropertyListImmutable * all objects in created list are immutable */ @@ -57,19 +62,22 @@ typedef enum { * Specifies the serialisation format for a serialised property list. */ typedef enum { - NSPropertyListGNUstepFormat, + NSPropertyListOpenStepFormat = 1, +/** NSPropertyListOpenStepFormat + * the most human-readable format */ + NSPropertyListXMLFormat_v1_0 = 100, +/** NSPropertyListXMLFormat_v1_0 + * portable and readable */ + NSPropertyListBinaryFormat_v1_0 = 200, +/** NSPropertyListBinaryFormat_v1_0 + * the standard format on macos-x */ + + NSPropertyListGNUstepFormat = 1000, /** NSPropertyListGNUstepFormat * extension of OpenStep format */ NSPropertyListGNUstepBinaryFormat, /** NSPropertyListGNUstepBinaryFormat * efficient, hardware independent */ - NSPropertyListOpenStepFormat, -/** NSPropertyListOpenStepFormat - * the most human-readable format */ - NSPropertyListXMLFormat_v1_0, -/** NSPropertyListXMLFormat_v1_0 - * portable and readable */ - NSPropertyListBinaryFormat_v1_0, } NSPropertyListFormat; /** @@ -246,5 +254,10 @@ typedef enum { @end -#endif /* STRICT_OPENSTEP */ +#endif /* GS_API_MACOSX */ + +#if defined(__cplusplus) +} +#endif + #endif /* __NSPropertyList_h_GNUSTEP_BASE_INCLUDE*/ diff --git a/Headers/Foundation/NSProtocolChecker.h b/Headers/Foundation/NSProtocolChecker.h index 1adcb17f6..96a0e5860 100644 --- a/Headers/Foundation/NSProtocolChecker.h +++ b/Headers/Foundation/NSProtocolChecker.h @@ -18,15 +18,20 @@ 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., 51 Franklin Street, Fifth Floor, Boston, - MA 02111 USA. + Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02111 USA. */ #ifndef __NSProtocolChecker_h_GNUSTEP_BASE_INCLUDE #define __NSProtocolChecker_h_GNUSTEP_BASE_INCLUDE +#import -#include -#include +#import +#import + +#if defined(__cplusplus) +extern "C" { +#endif @class Protocol; @@ -54,4 +59,8 @@ @end +#if defined(__cplusplus) +} +#endif + #endif diff --git a/Headers/Foundation/NSProxy.h b/Headers/Foundation/NSProxy.h index dddd0b2c6..f02de1a04 100644 --- a/Headers/Foundation/NSProxy.h +++ b/Headers/Foundation/NSProxy.h @@ -18,14 +18,19 @@ 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., 51 Franklin Street, Fifth Floor, Boston, - MA 02111 USA. + Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02111 USA. */ #ifndef __NSProxy_h_GNUSTEP_BASE_INCLUDE #define __NSProxy_h_GNUSTEP_BASE_INCLUDE +#import -#include +#import + +#if defined(__cplusplus) +extern "C" { +#endif @interface NSProxy { @@ -75,4 +80,8 @@ @end +#if defined(__cplusplus) +} +#endif + #endif /* __NSProxy_h_GNUSTEP_BASE_INCLUDE */ diff --git a/Headers/Foundation/NSRange.h b/Headers/Foundation/NSRange.h index a31b83e6b..cc14cd0b0 100644 --- a/Headers/Foundation/NSRange.h +++ b/Headers/Foundation/NSRange.h @@ -18,15 +18,21 @@ * * 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., 51 Franklin Street, Fifth Floor, Boston, - * MA 02111 USA. */ + * Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02111 USA. + */ #ifndef __NSRange_h_GNUSTEP_BASE_INCLUDE #define __NSRange_h_GNUSTEP_BASE_INCLUDE +#import /**** Included Headers *******************************************************/ -#include +#import + +#if defined(__cplusplus) +extern "C" { +#endif @class NSException; @class NXConstantString; @@ -81,7 +87,7 @@ struct _NSRange unsigned int length; }; -#ifndef STRICT_OPENSTEP +#if OS_API_VERSION(GS_API_MACOSX, GS_API_LATEST) /** Pointer to an NSRange structure. */ typedef NSRange *NSRangePointer; #endif @@ -222,7 +228,7 @@ GS_EXPORT NSRange NSRangeFromString(NSString *aString); #undef MIN #endif -#ifndef NO_GNUSTEP +#if OS_API_VERSION(GS_API_NONE, GS_API_NONE) /** * To be used inside a method for making sure that a range does not specify * anything outside the size of an array/string. Raises exception if range @@ -242,4 +248,8 @@ if (INDEX >= OVER) \ GSNameFromSelector(_cmd), INDEX] #endif +#if defined(__cplusplus) +} +#endif + #endif /* __NSRange_h_GNUSTEP_BASE_INCLUDE */ diff --git a/Headers/Foundation/NSRunLoop.h b/Headers/Foundation/NSRunLoop.h index 37219236f..9473cffd4 100644 --- a/Headers/Foundation/NSRunLoop.h +++ b/Headers/Foundation/NSRunLoop.h @@ -24,8 +24,13 @@ #ifndef __NSRunLoop_h_GNUSTEP_BASE_INCLUDE #define __NSRunLoop_h_GNUSTEP_BASE_INCLUDE +#import -#include +#import + +#if defined(__cplusplus) +extern "C" { +#endif @class NSTimer, NSDate, NSPort; @@ -145,4 +150,8 @@ typedef enum { all: (BOOL)removeAll; @end +#if defined(__cplusplus) +} +#endif + #endif /*__NSRunLoop_h_GNUSTEP_BASE_INCLUDE */ diff --git a/Headers/Foundation/NSScanner.h b/Headers/Foundation/NSScanner.h index 2c2e2cd77..018f3403e 100644 --- a/Headers/Foundation/NSScanner.h +++ b/Headers/Foundation/NSScanner.h @@ -18,16 +18,21 @@ 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., 51 Franklin Street, Fifth Floor, Boston, - MA 02111 USA. + Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02111 USA. */ -#ifndef __NSScanner_h_GNUSTEP_INCLUDE -#define __NSScanner_h_GNUSTEP_INCLUDE +#ifndef __NSScanner_h_GNUSTEP_BASE_INCLUDE +#define __NSScanner_h_GNUSTEP_BASE_INCLUDE +#import -#include -#include -#include +#import +#import +#import + +#if defined(__cplusplus) +extern "C" { +#endif /* * NSScanner class @@ -88,12 +93,16 @@ intoString: (NSString**)value; - (BOOL) isAtEnd; -#ifndef NO_GNUSTEP +#if OS_API_VERSION(GS_API_NONE, GS_API_NONE) - (BOOL) scanRadixUnsignedInt: (unsigned int*)value; #endif -#ifndef STRICT_OPENSTEP +#if OS_API_VERSION(GS_API_MACOSX, GS_API_LATEST) - (BOOL) scanDecimal: (NSDecimal*)value; #endif @end -#endif /* __NSScanner_h_GNUSTEP_INCLUDE */ +#if defined(__cplusplus) +} +#endif + +#endif /* __NSScanner_h_GNUSTEP_BASE_INCLUDE */ diff --git a/Headers/Foundation/NSSerialization.h b/Headers/Foundation/NSSerialization.h index c2ca8e379..5cebaae46 100644 --- a/Headers/Foundation/NSSerialization.h +++ b/Headers/Foundation/NSSerialization.h @@ -20,14 +20,19 @@ 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., 51 Franklin Street, Fifth Floor, Boston, - MA 02111 USA. + Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02111 USA. */ #ifndef __NSSerialization_h_GNUSTEP_BASE_INCLUDE #define __NSSerialization_h_GNUSTEP_BASE_INCLUDE +#import -#include +#import + +#if defined(__cplusplus) +extern "C" { +#endif @class NSData, NSMutableData; @@ -87,7 +92,7 @@ intoData: (NSMutableData*)d; @end -#ifndef NO_GNUSTEP +#if OS_API_VERSION(GS_API_NONE, GS_API_NONE) /** * GNUstep extends serialization by having the option to make the * resulting data more compact by ensuring that repeated strings @@ -163,7 +168,7 @@ @end -#ifndef NO_GNUSTEP +#if OS_API_VERSION(GS_API_NONE, GS_API_NONE) /** *

GNUstep extends deserialization by having the option to make the * resulting data more compact by ensuring that repeated strings @@ -187,4 +192,8 @@ #endif +#if defined(__cplusplus) +} +#endif + #endif /* __NSSerialization_h_GNUSTEP_BASE_INCLUDE */ diff --git a/Headers/Foundation/NSSet.h b/Headers/Foundation/NSSet.h index fc45deab6..949702ade 100644 --- a/Headers/Foundation/NSSet.h +++ b/Headers/Foundation/NSSet.h @@ -18,8 +18,8 @@ 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., 51 Franklin Street, Fifth Floor, Boston, - MA 02111 USA. + Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02111 USA. AutogsdocSource: NSSet.m AutogsdocSource: NSCountedSet.m @@ -28,8 +28,13 @@ #ifndef _NSSet_h_GNUSTEP_BASE_INCLUDE #define _NSSet_h_GNUSTEP_BASE_INCLUDE +#import -#include +#import + +#if defined(__cplusplus) +extern "C" { +#endif @class NSArray, NSString, NSEnumerator, NSDictionary; @@ -39,7 +44,7 @@ + (id) setWithArray: (NSArray*)objects; + (id) setWithObject: (id)anObject; + (id) setWithObjects: (id)firstObject, ...; -#ifndef STRICT_OPENSTEP +#if OS_API_VERSION(GS_API_MACOSX, GS_API_LATEST) + (id) setWithObjects: (id*)objects count: (unsigned)count; #endif @@ -66,7 +71,7 @@ - (void) makeObjectsPerform: (SEL)aSelector; - (void) makeObjectsPerform: (SEL)aSelector withObject: (id)argument; -#ifndef STRICT_OPENSTEP +#if OS_API_VERSION(GS_API_MACOSX, GS_API_LATEST) - (void) makeObjectsPerformSelector: (SEL)aSelector; - (void) makeObjectsPerformSelector: (SEL)aSelector withObject: (id)argument; #endif @@ -86,7 +91,7 @@ - (void) minusSet: (NSSet*)other; - (void) removeAllObjects; - (void) removeObject: (id)anObject; -#ifndef STRICT_OPENSTEP +#if OS_API_VERSION(GS_API_MACOSX, GS_API_LATEST) - (void) setSet: (NSSet*)other; #endif - (void) unionSet: (NSSet*)other; @@ -98,7 +103,7 @@ @end -#ifndef NO_GNUSTEP +#if OS_API_VERSION(GS_API_NONE, GS_API_NONE) /** * Utility methods for using a counted set to handle uniquing of objects. @@ -173,6 +178,10 @@ void GSUPurge(unsigned count); */ id GSUSet(id anObject, unsigned count); -#endif /* NO_GNUSTEP */ +#endif /* GS_API_NONE */ + +#if defined(__cplusplus) +} +#endif #endif diff --git a/Headers/Foundation/NSSortDescriptor.h b/Headers/Foundation/NSSortDescriptor.h index fafe9009f..fdd6ee147 100644 --- a/Headers/Foundation/NSSortDescriptor.h +++ b/Headers/Foundation/NSSortDescriptor.h @@ -18,52 +18,109 @@ 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., 51 Franklin Street, Fifth Floor, Boston, - MA 02111 USA. + Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02111 USA. */ #ifndef __NSSortDescriptor_h_GNUSTEP_BASE_INCLUDE #define __NSSortDescriptor_h_GNUSTEP_BASE_INCLUDE +#import -#include -#include +#if OS_API_VERSION(100300,GS_API_LATEST) + +#import +#import + +#if defined(__cplusplus) +extern "C" { +#endif @class NSString; +/** + * Instances of this class are used to perform multi-level sorts of + * arrays containging collections or other objects whose properties + * can be obtained using key names. + */ @interface NSSortDescriptor : NSObject { - NSString * _key; - BOOL _ascending; - SEL _selector; + NSString *_key; + BOOL _ascending; + SEL _selector; } -// initialization -- (id) initWithKey: (NSString *) key ascending: (BOOL) ascending; -- (id) initWithKey: (NSString *) key - ascending: (BOOL) ascending - selector: (SEL) selector; - -// getting information about a sort descriptor's setup +/** Returns a flag indicating whether the sort descriptor sorts objects + * in ascending order (YES) or descending order (NO). + */ - (BOOL) ascending; + +/** Returns the result of comparing object1 to object2 using the property + * whose key is defined in the receiver and using the selector of the + * receiver. If the receiver performs a descending order sort, the + * result of this comparison is the opposite of that prroduced by + * applying the selector. + */ +- (NSComparisonResult) compareObject: (id)object1 toObject: (id)object2; + +/** Initialises the receiver for comparisons using the 'compare:' selector + * and the specified key and ordering. + */ +- (id) initWithKey: (NSString *)key + ascending: (BOOL)ascending; + +/** + * Initialises the receiver to perform comparisons in the specified order + * using selector to compar the property key of each object. + */ +- (id) initWithKey: (NSString *)key + ascending: (BOOL)ascending + selector: (SEL)selector; + +/** Returns the key used to obtain the property on which comparisons are based. + */ - (NSString *) key; + +/** Returns the selector used to compare the properties of objects. + */ - (SEL) selector; -// using sort descriptors -- (NSComparisonResult) compareObject: (id) object1 toObject: (id) object2; +/** Returns a copy of the receiver which compares and sorts in reversed + * order. + */ - (id) reversedSortDescriptor; - @end @interface NSArray (NSSortDescriptorSorting) -- (NSArray *) sortedArrayUsingDescriptors: (NSArray *) sortDescriptors; +/** + * Produces a sorted array using the mechanism described for + * [NSMutableArray-sortUsingDescriptors:] + */ +- (NSArray *) sortedArrayUsingDescriptors: (NSArray *)sortDescriptors; @end @interface NSMutableArray (NSSortDescriptorSorting) -- (void) sortUsingDescriptors: (NSArray *) sortDescriptors; +/** + * This method works like this: first, it sorts the entire + * contents of the array using the first sort descriptor. Then, + * after each sort-run, it looks whether there are sort + * descriptors left to process, and if yes, looks at the partially + * sorted array, finds all portions in it which are equal + * (evaluate to NSOrderedSame) and applies the following + * descriptor onto them. It repeats this either until all + * descriptors have been applied or there are no more equal + * portions (equality ranges) left in the array. + */ +- (void) sortUsingDescriptors: (NSArray *)sortDescriptors; @end +#if defined(__cplusplus) +} +#endif + +#endif /* 100400 */ + #endif /* __NSSortDescriptor_h_GNUSTEP_BASE_INCLUDE */ diff --git a/Headers/Foundation/NSSpellServer.h b/Headers/Foundation/NSSpellServer.h new file mode 100644 index 000000000..67efca4b5 --- /dev/null +++ b/Headers/Foundation/NSSpellServer.h @@ -0,0 +1,135 @@ +/* + NSSpellServer.h + + Class to allow a spell checker to be available to other apps + + Copyright (C) 1996 Free Software Foundation, Inc. + + Author: Gregory John Casamento + Date: 2001 + + Author of previous version: Scott Christley + Date: 1996 + + 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; see the file COPYING.LIB. + If not, write to the Free Software Foundation, + 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ + +#ifndef _GNUstep_H_NSSpellServer +#define _GNUstep_H_NSSpellServer + +#import + +#import +#import + +#if defined(__cplusplus) +extern "C" { +#endif + +// Forward declarations +@class NSConnection; +@class NSMutableArray; +@class NSMutableDictionary; + +@interface NSSpellServer : NSObject +{ +@private + id _delegate; + BOOL _caseSensitive; + unsigned char _dummy[3]; + NSMutableDictionary *_userDictionaries; + NSString *_currentLanguage; + NSArray *_ignoredWords; + void *_reserved; +} + +// Checking in Your Service +- (BOOL) registerLanguage: (NSString *)language + byVendor: (NSString *)vendor; + +// Assigning a Delegate +- (id) delegate; +- (void) setDelegate: (id)anObject; + +// Running the Service +- (void) run; + +// Checking User Dictionaries +- (BOOL) isWordInUserDictionaries: (NSString *)word + caseSensitive: (BOOL)flag; +@end + +/** + This is an informal protocol since the + NSSpellChecker will need to use a proxy object + to call these methods. + + These methods need to be implemented by the spell service + so that the NSSpellServer instance call call them when + necessary. +*/ +@interface NSObject (NSSpellServerDelegate) +/** + *

+ * This method is called when the user begins spell checking the document. + * The parameters are: sender the spell server instance which + * invoked this method, stringToCheck this is the string which + * the spell service is going to attempt to find misspelled words in, + * language the language to check in, wordCount the + * number of words checked, and countOnly a flag which dictates + * if them method checks the spelling or just counts the words in the given + * string. + *

+ *

+ * Returns a range for any word it finds that is misspelled. + *

+ */ +- (NSRange) spellServer: (NSSpellServer *)sender +findMisspelledWordInString: (NSString *)stringToCheck + language: (NSString *)language + wordCount: (int *)wordCount + countOnly: (BOOL)countOnly; + +/** + * Attempts to guess the correct spelling of word. + */ +- (NSArray *) spellServer: (NSSpellServer *)sender + suggestGuessesForWord: (NSString *)word + inLanguage: (NSString *)language; + +/** + * Records the new word in the user's dictionary for the given language. + */ +- (void) spellServer: (NSSpellServer *)sender + didLearnWord: (NSString *)word + inLanguage: (NSString *)language; + +/** + * Forgets the given word in the user's dictionary for the given language. + */ +- (void) spellServer: (NSSpellServer *)sender + didForgetWord: (NSString *)word + inLanguage: (NSString *)language; +@end + +#if defined(__cplusplus) +} +#endif + +#endif // _GNUstep_H_NSSpellServer diff --git a/Headers/Foundation/NSStream.h b/Headers/Foundation/NSStream.h index d24b17dce..7df6c8fb9 100644 --- a/Headers/Foundation/NSStream.h +++ b/Headers/Foundation/NSStream.h @@ -23,11 +23,16 @@ #ifndef __NSStream_h_GNUSTEP_BASE_INCLUDE #define __NSStream_h_GNUSTEP_BASE_INCLUDE - -#include +#import #if OS_API_VERSION(100400,GS_API_LATEST) && GS_API_VERSION(010200,GS_API_LATEST) +#import + +#if defined(__cplusplus) +extern "C" { +#endif + typedef enum { NSStreamStatusNotOpen = 0, NSStreamStatusOpening = 1, @@ -331,6 +336,10 @@ GS_EXPORT NSString * const NSStreamSOCKSProxyVersionKey; - (void) stream: (NSStream*)sStream handleEvent: (NSStreamEvent)anEvent; @end +#if defined(__cplusplus) +} #endif -#endif /* __NSStream_h_GNUSTEP_BASE_INCLUDE */ +#endif /* 100200 */ + +#endif /* __NSStream_h_GNUSTEP_BASE_INCLUDE */ diff --git a/Headers/Foundation/NSString.h b/Headers/Foundation/NSString.h index 57613a888..ecf0e2176 100644 --- a/Headers/Foundation/NSString.h +++ b/Headers/Foundation/NSString.h @@ -24,9 +24,14 @@ #ifndef __NSString_h_GNUSTEP_BASE_INCLUDE #define __NSString_h_GNUSTEP_BASE_INCLUDE +#import -#include -#include +#import +#import + +#if defined(__cplusplus) +extern "C" { +#endif /** * Type for representing unicode characters. (16-bit) @@ -37,7 +42,7 @@ typedef unsigned short unichar; @class NSCharacterSet; @class NSData; @class NSDictionary; -#ifndef STRICT_OPENSTEP +#if OS_API_VERSION(GS_API_MACOSX, GS_API_LATEST) @class NSURL; #endif @@ -48,7 +53,8 @@ enum NSCaseInsensitiveSearch = 1, NSLiteralSearch = 2, NSBackwardsSearch = 4, - NSAnchoredSearch = 8 + NSAnchoredSearch = 8, + NSNumericSearch = 64 /* MacOS-X 10.2 */ }; /** @@ -100,7 +106,6 @@ typedef enum _NSStringEncoding NSMacOSRomanStringEncoding = 30, NSProprietaryStringEncoding = 31, -// GNUstep additions NSKOI8RStringEncoding = 50, // Russian/Cyrillic NSISOLatin3StringEncoding = 51, // ISO-8859-3; South European NSISOLatin4StringEncoding = 52, // ISO-8859-4; North European @@ -282,7 +287,7 @@ enum { // Getting C Strings - (const char*) cString; -#ifndef STRICT_OPENSTEP +#if OS_API_VERSION(GS_API_MACOSX, GS_API_LATEST) #if OS_API_VERSION(100400,GS_API_LATEST) && GS_API_VERSION(010200,GS_API_LATEST) - (const char*) cStringUsingEncoding: (NSStringEncoding)encoding; @@ -533,7 +538,7 @@ enum { // for methods working with decomposed strings - (int) _baseLength; -#ifndef STRICT_OPENSTEP +#if OS_API_VERSION(GS_API_MACOSX, GS_API_LATEST) /** * Concatenates the path components in the array and returns the result.
* This method does not remove empty path components, but does recognize an @@ -614,10 +619,10 @@ enum { - (const char *)UTF8String; #endif -#ifndef NO_GNUSTEP +#if OS_API_VERSION(GS_API_NONE, GS_API_NONE) + (Class) constantStringClass; - (BOOL) boolValue; -#endif /* NO_GNUSTEP */ +#endif /* GS_API_NONE */ @end @@ -689,7 +694,7 @@ enum { extern struct objc_class _NSConstantStringClassReference; #endif -#ifndef NO_GNUSTEP +#if OS_API_VERSION(GS_API_NONE, GS_API_NONE) @interface NSMutableString (GNUstep) - (NSString*) immutableProxy; @@ -793,6 +798,10 @@ extern struct objc_class _NSConstantStringClassReference; - (void) trimSpaces; @end -#endif /* NO_GNUSTEP */ +#endif /* GS_API_NONE */ + +#if defined(__cplusplus) +} +#endif #endif /* __NSString_h_GNUSTEP_BASE_INCLUDE */ diff --git a/Headers/Foundation/NSTask.h b/Headers/Foundation/NSTask.h index 74b5228d2..352d6ccde 100644 --- a/Headers/Foundation/NSTask.h +++ b/Headers/Foundation/NSTask.h @@ -18,18 +18,23 @@ 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., 51 Franklin Street, Fifth Floor, Boston, - MA 02111 USA. + Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02111 USA. */ #ifndef __NSTask_h_GNUSTEP_BASE_INCLUDE #define __NSTask_h_GNUSTEP_BASE_INCLUDE +#import -#include -#include -#include -#include -#include +#import +#import +#import +#import +#import + +#if defined(__cplusplus) +extern "C" { +#endif @interface NSTask : NSObject { @@ -77,7 +82,7 @@ * Obtaining task state */ - (BOOL) isRunning; -#ifndef STRICT_OPENSTEP +#if OS_API_VERSION(GS_API_MACOSX, GS_API_LATEST) - (int) processIdentifier; #endif - (int) terminationStatus; @@ -87,14 +92,14 @@ */ - (void) interrupt; - (void) launch; -#ifndef STRICT_OPENSTEP +#if OS_API_VERSION(GS_API_MACOSX, GS_API_LATEST) - (BOOL) resume; - (BOOL) suspend; #endif - (void) terminate; - (void) waitUntilExit; -#ifndef NO_GNUSTEP +#if OS_API_VERSION(GS_API_NONE, GS_API_NONE) - (BOOL) usePseudoTerminal; - (NSString*) validatedLaunchPath; #endif @@ -107,4 +112,8 @@ */ GS_EXPORT NSString* const NSTaskDidTerminateNotification; +#if defined(__cplusplus) +} +#endif + #endif /* __NSTask_h_GNUSTEP_BASE_INCLUDE */ diff --git a/Headers/Foundation/NSThread.h b/Headers/Foundation/NSThread.h index 7c6268232..d5e829b65 100644 --- a/Headers/Foundation/NSThread.h +++ b/Headers/Foundation/NSThread.h @@ -19,17 +19,22 @@ 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., 51 Franklin Street, Fifth Floor, Boston, - MA 02111 USA. + Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02111 USA. */ #ifndef __NSThread_h_GNUSTEP_BASE_INCLUDE #define __NSThread_h_GNUSTEP_BASE_INCLUDE +#import -#include -#include -#include -#include // for struct autorelease_thread_vars +#import +#import +#import +#import // for struct autorelease_thread_vars + +#if defined(__cplusplus) +extern "C" { +#endif @interface NSThread : NSObject { @@ -58,7 +63,7 @@ @end -#ifndef STRICT_OPENSTEP +#if GS_API_VERSION(GS_API_MACOSX, GS_API_LATEST) @interface NSObject(NSMainThreadPerformAdditions) - (void) performSelectorOnMainThread: (SEL)aSelector withObject: (id)anObject @@ -70,7 +75,7 @@ @end #endif -#ifndef NO_GNUSTEP +#if GS_API_VERSION(GS_API_NONE, GS_API_NONE) /* * Don't use the following functions unless you really know what you are * doing ! @@ -129,7 +134,7 @@ GS_EXPORT NSString* const NSWillBecomeMultiThreadedNotification; GS_EXPORT NSString* const NSThreadWillExitNotification; #define NSThreadExiting NSThreadWillExitNotification -#ifndef NO_GNUSTEP +#if GS_API_VERSION(GS_API_NONE, GS_API_NONE) /** * Notification posted whenever a new thread is started up. This is a @@ -144,4 +149,8 @@ GS_EXPORT NSThread *GSCurrentThread(void); GS_EXPORT NSMutableDictionary *GSCurrentThreadDictionary(void); #endif +#if defined(__cplusplus) +} +#endif + #endif /* __NSThread_h_GNUSTEP_BASE_INCLUDE */ diff --git a/Headers/Foundation/NSTimeZone.h b/Headers/Foundation/NSTimeZone.h index 778b82ae8..99a7f583a 100644 --- a/Headers/Foundation/NSTimeZone.h +++ b/Headers/Foundation/NSTimeZone.h @@ -15,14 +15,19 @@ 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., 51 Franklin Street, Fifth Floor, Boston, - MA 02111 USA. + Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02111 USA. */ #ifndef __NSTimeZone_h_GNUSTEP_BASE_INCLUDE #define __NSTimeZone_h_GNUSTEP_BASE_INCLUDE +#import -#include +#import + +#if defined(__cplusplus) +extern "C" { +#endif @class NSArray; @class NSDate; @@ -47,13 +52,13 @@ + (NSArray*) timeZoneArray; - (NSArray*) timeZoneDetailArray; -#ifndef NO_GNUSTEP +#if OS_API_VERSION(GS_API_NONE, GS_API_NONE) /* Returns an dictionary that maps abbreviations to the array containing all the time zone names that use the abbreviation. */ + (NSDictionary*) abbreviationMap; #endif -#ifndef STRICT_OPENSTEP +#if OS_API_VERSION(GS_API_MACOSX, GS_API_NONE) + (void) resetSystemTimeZone; + (NSTimeZone*) systemTimeZone; + (NSTimeZone*) timeZoneWithName: (NSString*)name data: (NSData*)data; @@ -70,7 +75,7 @@ - (int) secondsFromGMTForDate: (NSDate*)aDate; #endif -#ifndef STRICT_MACOS_X +#if OS_API_VERSION(GS_API_OPENSTEP, GS_API_MACOSX) - (NSTimeZoneDetail*) timeZoneDetailForDate: (NSDate*)date; - (NSString*) timeZoneName; #endif @@ -84,7 +89,7 @@ + (NSTimeZone*) timeZoneWithAbbreviation: (NSString*)abbreviation; @end -#ifndef STRICT_MACOS_X +#if OS_API_VERSION(GS_API_OPENSTEP, GS_API_MACOSX) @interface NSTimeZoneDetail : NSTimeZone - (BOOL) isDaylightSavingTimeZone; - (NSString*) timeZoneAbbreviation; @@ -92,5 +97,9 @@ @end #endif +#if defined(__cplusplus) +} +#endif + #endif /* __NSTimeZone_h_GNUSTEP_BASE_INCLUDE*/ diff --git a/Headers/Foundation/NSTimer.h b/Headers/Foundation/NSTimer.h index 372faecfa..066b6aae7 100644 --- a/Headers/Foundation/NSTimer.h +++ b/Headers/Foundation/NSTimer.h @@ -18,17 +18,22 @@ 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., 51 Franklin Street, Fifth Floor, Boston, - MA 02111 USA. + Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02111 USA. */ -#ifndef __NSTimer_include__ -#define __NSTimer_include__ +#ifndef __NSTimer_h_GNUSTEP_BASE_INCLUDE +#define __NSTimer_h_GNUSTEP_BASE_INCLUDE +#import /* This class is currently thrown together. When it is cleaned up, it may no longer be concrete. */ -#include +#import + +#if defined(__cplusplus) +extern "C" { +#endif /* * NB. NSRunLoop is optimised using a hack that knows about the @@ -72,7 +77,7 @@ - (id) userInfo; -#ifndef STRICT_OPENSTEP +#if OS_API_VERSION(GS_API_MACOSX, GS_API_LATEST) - (id) initWithFireDate: (NSDate*)fd interval: (NSTimeInterval)ti target: (id)object @@ -86,4 +91,8 @@ @end +#if defined(__cplusplus) +} #endif + +#endif /* __NSTimer_h_GNUSTEP_BASE_INCLUDE */ diff --git a/Headers/Foundation/NSURL.h b/Headers/Foundation/NSURL.h index e18f7bffb..6dad0bcaf 100644 --- a/Headers/Foundation/NSURL.h +++ b/Headers/Foundation/NSURL.h @@ -18,16 +18,21 @@ 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., 51 Franklin Street, Fifth Floor, Boston, - MA 02111 USA. + Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02111 USA. */ -#ifndef _NSURL_h__ -#define _NSURL_h__ +#ifndef __NSURL_h_GNUSTEP_BASE_INCLUDE +#define __NSURL_h_GNUSTEP_BASE_INCLUDE +#import -#include +#import -#ifndef STRICT_OPENSTEP +#if defined(__cplusplus) +extern "C" { +#endif + +#if OS_API_VERSION(GS_API_MACOSX, GS_API_LATEST) @class NSNumber; @@ -112,6 +117,11 @@ GS_EXPORT NSString* const NSURLFileScheme; resourceDidFailLoadingWithReason: (NSString*)reason; @end +#endif /* GS_API_MACOSX */ + +#if defined(__cplusplus) +} #endif -#endif //_NSUrl_h__ +#endif /* __NSURL_h_GNUSTEP_BASE_INCLUDE */ + diff --git a/Headers/Foundation/NSURLAuthenticationChallenge.h b/Headers/Foundation/NSURLAuthenticationChallenge.h index 13630cd4f..5050c8fad 100644 --- a/Headers/Foundation/NSURLAuthenticationChallenge.h +++ b/Headers/Foundation/NSURLAuthenticationChallenge.h @@ -24,11 +24,16 @@ #ifndef __NSURLAuthenticationChallenge_h_GNUSTEP_BASE_INCLUDE #define __NSURLAuthenticationChallenge_h_GNUSTEP_BASE_INCLUDE - -#include +#import #if OS_API_VERSION(100200,GS_API_LATEST) && GS_API_VERSION(011300,GS_API_LATEST) +#import + +#if defined(__cplusplus) +extern "C" { +#endif + @class NSError; @class NSURLAuthenticationChallenge; @class NSURLCredential; @@ -141,5 +146,10 @@ @end +#if defined(__cplusplus) +} #endif + +#endif + #endif diff --git a/Headers/Foundation/NSURLCache.h b/Headers/Foundation/NSURLCache.h index be021900e..2dec90d28 100644 --- a/Headers/Foundation/NSURLCache.h +++ b/Headers/Foundation/NSURLCache.h @@ -24,11 +24,16 @@ #ifndef __NSURLCache_h_GNUSTEP_BASE_INCLUDE #define __NSURLCache_h_GNUSTEP_BASE_INCLUDE - -#include +#import #if OS_API_VERSION(100200,GS_API_LATEST) && GS_API_VERSION(011300,GS_API_LATEST) +#import + +#if defined(__cplusplus) +extern "C" { +#endif + @class NSData; @class NSDictionary; @class NSURLRequest; @@ -189,5 +194,10 @@ typedef enum @end +#if defined(__cplusplus) +} #endif + +#endif + #endif diff --git a/Headers/Foundation/NSURLConnection.h b/Headers/Foundation/NSURLConnection.h index 5e8fcc8f6..b38ea0762 100644 --- a/Headers/Foundation/NSURLConnection.h +++ b/Headers/Foundation/NSURLConnection.h @@ -24,11 +24,16 @@ #ifndef __NSURLConnection_h_GNUSTEP_BASE_INCLUDE #define __NSURLConnection_h_GNUSTEP_BASE_INCLUDE - -#include +#import #if OS_API_VERSION(100200,GS_API_LATEST) && GS_API_VERSION(011300,GS_API_LATEST) +#import + +#if defined(__cplusplus) +extern "C" { +#endif + @class NSCachedURLResponse; @class NSData; @class NSError; @@ -224,5 +229,10 @@ @end +#if defined(__cplusplus) +} #endif + +#endif + #endif diff --git a/Headers/Foundation/NSURLCredential.h b/Headers/Foundation/NSURLCredential.h index f6d2c849c..94f53486f 100644 --- a/Headers/Foundation/NSURLCredential.h +++ b/Headers/Foundation/NSURLCredential.h @@ -24,11 +24,16 @@ #ifndef __NSURLCredential_h_GNUSTEP_BASE_INCLUDE #define __NSURLCredential_h_GNUSTEP_BASE_INCLUDE - -#include +#import #if OS_API_VERSION(100200,GS_API_LATEST) && GS_API_VERSION(011300,GS_API_LATEST) +#import + +#if defined(__cplusplus) +extern "C" { +#endif + @class NSString; /** @@ -101,5 +106,10 @@ typedef enum { @end +#if defined(__cplusplus) +} #endif + +#endif + #endif diff --git a/Headers/Foundation/NSURLCredentialStorage.h b/Headers/Foundation/NSURLCredentialStorage.h index 142568f53..273d1073b 100644 --- a/Headers/Foundation/NSURLCredentialStorage.h +++ b/Headers/Foundation/NSURLCredentialStorage.h @@ -24,11 +24,16 @@ #ifndef __NSURLCredentialStorage_h_GNUSTEP_BASE_INCLUDE #define __NSURLCredentialStorage_h_GNUSTEP_BASE_INCLUDE - -#include +#import #if OS_API_VERSION(100200,GS_API_LATEST) && GS_API_VERSION(011300,GS_API_LATEST) +#import + +#if defined(__cplusplus) +extern "C" { +#endif + @class NSDictionary; @class NSString; @class NSURLCredential; @@ -99,5 +104,10 @@ extern NSString *const NSURLCredentialStorageChangedNotification; @end +#if defined(__cplusplus) +} #endif + +#endif + #endif diff --git a/Headers/Foundation/NSURLDownload.h b/Headers/Foundation/NSURLDownload.h index f60b1abaa..c2d99d818 100644 --- a/Headers/Foundation/NSURLDownload.h +++ b/Headers/Foundation/NSURLDownload.h @@ -24,11 +24,16 @@ #ifndef __NSURLDownload_h_GNUSTEP_BASE_INCLUDE #define __NSURLDownload_h_GNUSTEP_BASE_INCLUDE - -#include +#import #if OS_API_VERSION(100200,GS_API_LATEST) && GS_API_VERSION(011300,GS_API_LATEST) +#import + +#if defined(__cplusplus) +extern "C" { +#endif + @class NSData; @class NSError; @class NSString; @@ -202,5 +207,10 @@ @end +#if defined(__cplusplus) +} #endif + +#endif + #endif diff --git a/Headers/Foundation/NSURLError.h b/Headers/Foundation/NSURLError.h index 9f3c28899..942874165 100644 --- a/Headers/Foundation/NSURLError.h +++ b/Headers/Foundation/NSURLError.h @@ -24,11 +24,16 @@ #ifndef __NSURLError_h_GNUSTEP_BASE_INCLUDE #define __NSURLError_h_GNUSTEP_BASE_INCLUDE - -#include +#import #if OS_API_VERSION(100200,GS_API_LATEST) && GS_API_VERSION(011300,GS_API_LATEST) +#import + +#if defined(__cplusplus) +extern "C" { +#endif + @class NSString; /** @@ -84,5 +89,10 @@ enum NSURLErrorDownloadDecodingFailedToComplete = -3007, }; +#if defined(__cplusplus) +} #endif + +#endif + #endif diff --git a/Headers/Foundation/NSURLHandle.h b/Headers/Foundation/NSURLHandle.h index 9938a4f74..adb98b51d 100644 --- a/Headers/Foundation/NSURLHandle.h +++ b/Headers/Foundation/NSURLHandle.h @@ -18,16 +18,21 @@ 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., 51 Franklin Street, Fifth Floor, Boston, - MA 02111 USA. + Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02111 USA. */ -#ifndef _NSURLHandle_h__ -#define _NSURLHandle_h__ +#ifndef __NSURLHandle_h_GNUSTEP_BASE_INCLUDE +#define __NSURLHandle_h_GNUSTEP_BASE_INCLUDE +#import -#include +#if OS_API_VERSION(GS_API_MACOSX, GS_API_LATEST) -#ifndef STRICT_OPENSTEP +#import + +#if defined(__cplusplus) +extern "C" { +#endif @class NSData; @class NSString; @@ -66,7 +71,7 @@ GS_EXPORT NSString * const NSHTTPPropertyRedirectionHeadersKey; */ GS_EXPORT NSString * const NSHTTPPropertyErrorPageDataKey; -#ifndef NO_GNUSTEP +#if OS_API_VERSION(GS_API_NONE, GS_API_NONE) /** * Key for passing to [NSURLHandle]'s propertyForKey.. methods to @@ -210,6 +215,11 @@ typedef enum @end +#if defined(__cplusplus) +} #endif #endif + +#endif /* __NSURLHandle_h_GNUSTEP_BASE_INCLUDE */ + diff --git a/Headers/Foundation/NSURLProtectionSpace.h b/Headers/Foundation/NSURLProtectionSpace.h index 347b25fb6..2230a598e 100644 --- a/Headers/Foundation/NSURLProtectionSpace.h +++ b/Headers/Foundation/NSURLProtectionSpace.h @@ -24,11 +24,16 @@ #ifndef __NSURLProtectionSpace_h_GNUSTEP_BASE_INCLUDE #define __NSURLProtectionSpace_h_GNUSTEP_BASE_INCLUDE - -#include +#import #if OS_API_VERSION(100200,GS_API_LATEST) && GS_API_VERSION(011300,GS_API_LATEST) +#import + +#if defined(__cplusplus) +extern "C" { +#endif + @class NSString; extern NSString * const NSURLProtectionSpaceFTPProxy; /** An FTP proxy */ @@ -125,5 +130,10 @@ authenticationMethod: (NSString *)authenticationMethod; @end +#if defined(__cplusplus) +} #endif + +#endif + #endif diff --git a/Headers/Foundation/NSURLProtocol.h b/Headers/Foundation/NSURLProtocol.h index 8a8c2756b..53ff2b125 100644 --- a/Headers/Foundation/NSURLProtocol.h +++ b/Headers/Foundation/NSURLProtocol.h @@ -24,12 +24,17 @@ #ifndef __NSURLProtocol_h_GNUSTEP_BASE_INCLUDE #define __NSURLProtocol_h_GNUSTEP_BASE_INCLUDE - -#include +#import #if OS_API_VERSION(100200,GS_API_LATEST) && GS_API_VERSION(011300,GS_API_LATEST) -#include +#import + +#if defined(__cplusplus) +extern "C" { +#endif + +#import @class NSCachedURLResponse; @class NSError; @@ -218,5 +223,10 @@ @end +#if defined(__cplusplus) +} #endif + +#endif + #endif diff --git a/Headers/Foundation/NSURLRequest.h b/Headers/Foundation/NSURLRequest.h index e2addf86b..324bf1f95 100644 --- a/Headers/Foundation/NSURLRequest.h +++ b/Headers/Foundation/NSURLRequest.h @@ -24,11 +24,16 @@ #ifndef __NSURLRequest_h_GNUSTEP_BASE_INCLUDE #define __NSURLRequest_h_GNUSTEP_BASE_INCLUDE - -#include +#import #if OS_API_VERSION(100200,GS_API_LATEST) && GS_API_VERSION(011300,GS_API_LATEST) +#import + +#if defined(__cplusplus) +extern "C" { +#endif + @class NSData; @class NSDate; @class NSDictionary; @@ -271,5 +276,10 @@ typedef enum @end +#if defined(__cplusplus) +} #endif + +#endif + #endif diff --git a/Headers/Foundation/NSURLResponse.h b/Headers/Foundation/NSURLResponse.h index 43fd161f4..e503fedc8 100644 --- a/Headers/Foundation/NSURLResponse.h +++ b/Headers/Foundation/NSURLResponse.h @@ -24,11 +24,16 @@ #ifndef __NSURLResponse_h_GNUSTEP_BASE_INCLUDE #define __NSURLResponse_h_GNUSTEP_BASE_INCLUDE - -#include +#import #if OS_API_VERSION(100200,GS_API_LATEST) && GS_API_VERSION(011300,GS_API_LATEST) +#import + +#if defined(__cplusplus) +extern "C" { +#endif + @class NSDictionary; @class NSString; @@ -116,5 +121,10 @@ @end +#if defined(__cplusplus) +} #endif + +#endif + #endif diff --git a/Headers/Foundation/NSUndoManager.h b/Headers/Foundation/NSUndoManager.h index 1e969aa7f..05b41d943 100644 --- a/Headers/Foundation/NSUndoManager.h +++ b/Headers/Foundation/NSUndoManager.h @@ -17,14 +17,21 @@ 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., 51 Franklin Street, Fifth Floor, Boston, - MA 02111 USA. + Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02111 USA. */ #ifndef __NSUndoManager_h_OBJECTS_INCLUDE #define __NSUndoManager_h_OBJECTS_INCLUDE +#import -#include +#if OS_API_VERSION(GS_API_MACOSX, GS_API_LATEST) + +#import + +#if defined(__cplusplus) +extern "C" { +#endif @class NSArray; @class NSString; @@ -128,4 +135,10 @@ GS_EXPORT NSString* const NSUndoManagerWillUndoChangeNotification; @end +#if defined(__cplusplus) +} +#endif + +#endif /* GS_API_MACOSX */ + #endif /* __NSUndoManager_h_OBJECTS_INCLUDE */ diff --git a/Headers/Foundation/NSUserDefaults.h b/Headers/Foundation/NSUserDefaults.h index f5a8e8174..db239f124 100644 --- a/Headers/Foundation/NSUserDefaults.h +++ b/Headers/Foundation/NSUserDefaults.h @@ -25,10 +25,15 @@ #ifndef __NSUserDefaults_h_OBJECTS_INCLUDE #define __NSUserDefaults_h_OBJECTS_INCLUDE +#include #include #include +#if defined(__cplusplus) +extern "C" { +#endif + @class NSArray; @class NSMutableArray; @class NSDictionary; @@ -125,7 +130,7 @@ GS_EXPORT NSString* const NSDecimalDigits; /** Key for locale dictionary: array of strings for AM and PM. */ GS_EXPORT NSString* const NSAMPMDesignation; -#ifndef STRICT_OPENSTEP +#if OS_API_VERSION(GSAPI_MACOSX, GSAPI_LAST) /** * Array of arrays of NSStrings, first member of each specifying a time, @@ -222,69 +227,278 @@ GS_EXPORT NSString* const NSLocale; NSDistributedLock *_fileLock; } -/* Getting the Shared Instance */ +/** + * Returns the shared defaults object. If it doesn't exist yet, it's + * created. The defaults are initialized for the current user. + * The search list is guaranteed to be standard only the first time + * this method is invoked. The shared instance is provided as a + * convenience; other instances may also be created. + */ + (NSUserDefaults*) standardUserDefaults; -#ifndef STRICT_OPENSTEP -/* - * Called by GSSetUserName() to get the defaults system to use the defaults - * of a new user. + +#if OS_API_VERSION(GSAPI_MACOSX, GSAPI_LAST) +/** + * Resets the shared user defaults object to reflect the current + * user ID. Needed by setuid processes which change the user they + * are running as.
+ * In GNUstep you should call GSSetUserName() when changing your + * effective user ID, and that function will call this function for you. */ + (void) resetStandardUserDefaults; #endif -#ifndef STRICT_OPENSTEP -#ifndef STRICT_MACOS_X + +#if OS_API_VERSION(GSAPI_NONE, GSAPI_NONE) +/** + * Returns the array of user languages preferences. Uses the + * NSLanguages user default if available, otherwise + * tries to infer setup from operating system information etc + * (in particular, uses the LANGUAGES environment variable). + */ + (NSArray*) userLanguages; + +/** + * Sets the array of user languages preferences. Places the specified + * array in the NSLanguages user default. + */ + (void) setUserLanguages: (NSArray*)languages; #endif + +#if OS_API_VERSION(GSAPI_MACOSX, GSAPI_LAST) +/** + * Adds the domain names aName to the search list of the receiver.
+ * The domain is added after the application domain.
+ * Suites may be removed using the -removeSuiteNamed: method. + */ +- (void) addSuiteNamed: (NSString*)aName; #endif -/* Initializing the User Defaults */ +/** + * Looks up a value for a specified default using -objectForKey: + * and checks that it is an NSArray object. Returns nil if it is not. + */ +- (NSArray*) arrayForKey: (NSString*)defaultName; + +/** + * Looks up a value for a specified default using -objectForKey: + * and returns its boolean representation.
+ * Returns NO if it is not a boolean.
+ * The text 'yes' or 'true' or any non zero numeric value is considered + * to be a boolean YES. Other string values are NO.
+ * NB. This differs slightly from the documented behavior for MacOS-X + * (August 2002) in that the GNUstep version accepts the string 'TRUE' + * as equivalent to 'YES'. + */ +- (BOOL) boolForKey: (NSString*)defaultName; + +/** + * Looks up a value for a specified default using -objectForKey: + * and checks that it is an NSData object. Returns nil if it is not. + */ +- (NSData*) dataForKey: (NSString*)defaultName; + +/** + * Looks up a value for a specified default using -objectForKey: + * and checks that it is an NSDictionary object. Returns nil if it is not. + */ +- (NSDictionary*) dictionaryForKey: (NSString*)defaultName; + +/** + * Looks up a value for a specified default using -objectForKey: + * and checks that it is a float. Returns 0.0 if it is not. + */ +- (float) floatForKey: (NSString*)defaultName; + +/** + * Initializes defaults for current user calling initWithUser: + */ - (id) init; + +/** + * Initializes defaults for the specified user calling -initWithContentsOfFile: + */ - (id) initWithUser: (NSString*)userName; + +/** + * + * Initializes defaults for the specified path. Returns an object with + * an empty search list. + */ - (id) initWithContentsOfFile: (NSString*)path; // This is a new method -/* Getting and Setting a Default */ -- (NSArray*) arrayForKey: (NSString*)defaultName; -- (BOOL) boolForKey: (NSString*)defaultName; -- (NSData*) dataForKey: (NSString*)defaultName; -- (NSDictionary*) dictionaryForKey: (NSString*)defaultName; -- (float) floatForKey: (NSString*)defaultName; +/** + * Looks up a value for a specified default using -objectForKey: + * and returns its integer value or 0 if it is not representable + * as an integer. + */ - (int) integerForKey: (NSString*)defaultName; -- (id) objectForKey: (NSString*)defaultName; -- (void) removeObjectForKey: (NSString*)defaultName; -- (void) setBool: (BOOL)value forKey: (NSString*)defaultName; -- (void) setFloat: (float)value forKey: (NSString*)defaultName; -- (void) setInteger: (int)value forKey: (NSString*)defaultName; -- (void) setObject: (id)value forKey: (NSString*)defaultName; -- (NSArray*) stringArrayForKey: (NSString*)defaultName; -- (NSString*) stringForKey: (NSString*)defaultName; -/* Returning the Search List */ -- (NSArray*) searchList; -- (void) setSearchList: (NSArray*)newList; -#ifndef STRICT_OPENSTEP -- (void) addSuiteNamed: (NSString*)aName; +/** + * Looks up a value for a specified default using. + * The lookup is performed by accessing the domains in the order + * given in the search list. + *
Returns nil if defaultName cannot be found. + */ +- (id) objectForKey: (NSString*)defaultName; + +/** + * Removes the default with the specified name from the application + * domain. + */ +- (void) removeObjectForKey: (NSString*)defaultName; + +#if OS_API_VERSION(GSAPI_MACOSX, GSAPI_LAST) +/** + * Removes the named domain from the search list of the receiver.
+ * Suites may be added using the -addSuiteNamed: method. + */ - (void) removeSuiteNamed: (NSString*)aName; #endif -/* Maintaining Persistent Domains */ +/** + * Returns an array listing the domains searched in order to look up + * a value in the defaults system. The order of the names in the + * array is the order in which the domains are searched. + */ +- (NSArray*) searchList; + +/** + * Sets a boolean value for defaultName in the application domain.
+ * Calls -setObject:forKey: to make the change by storing a boolean + * [NSNumber] instance. + */ +- (void) setBool: (BOOL)value forKey: (NSString*)defaultName; + +/** + * Sets a float value for defaultName in the application domain.
+ * Calls -setObject:forKey: to make the change by storing a float + * [NSNumber] instance. + */ +- (void) setFloat: (float)value forKey: (NSString*)defaultName; + +/** + * Sets an integer value for defaultName in the application domain.
+ * Calls -setObject:forKey: to make the change by storing an intege + * [NSNumber] instance. + */ +- (void) setInteger: (int)value forKey: (NSString*)defaultName; + +/** + * Sets an object value for defaultName in the application domain.
+ * The defaultName must be a non-empty string.
+ * The value must be an instance of one of the [NSString-propertyList] + * classes.
+ *

Causes a NSUserDefaultsDidChangeNotification to be posted + * if this is the first change to a persistent-domain since the + * last -synchronize. + *

+ * If value is nil, this is equivalent to the -removeObjectForKey: method. + */ +- (void) setObject: (id)value forKey: (NSString*)defaultName; + +/** + * Sets the list of the domains searched in order to look up + * a value in the defaults system. The order of the names in the + * array is the order in which the domains are searched.
+ * On lookup, the first match is used. + */ +- (void) setSearchList: (NSArray*)newList; + +/** + * Calls -arrayForKey: to get an array value for defaultName and checks + * that the array contents are string objects ... if not, returns nil. + */ +- (NSArray*) stringArrayForKey: (NSString*)defaultName; + +/** + * Looks up a value for a specified default using -objectForKey: + * and checks that it is an NSString. Returns nil if it is not. + */ +- (NSString*) stringForKey: (NSString*)defaultName; + +/** + * Returns the persistent domain specified by domainName. + */ - (NSDictionary*) persistentDomainForName: (NSString*)domainName; + +/** + * Returns an array listing the name of all the persistent domains. + */ - (NSArray*) persistentDomainNames; + +/** + * Removes the persistent domain specified by domainName from the + * user defaults. + *
Causes a NSUserDefaultsDidChangeNotification to be posted + * if this is the first change to a persistent-domain since the + * last -synchronize. + */ - (void) removePersistentDomainForName: (NSString*)domainName; + +/** + * Replaces the persistent-domain specified by domainName with + * domain ... a dictionary containing keys and defaults values. + *
Raises an NSInvalidArgumentException if domainName already + * exists as a volatile-domain. + *
Causes a NSUserDefaultsDidChangeNotification to be posted + * if this is the first change to a persistent-domain since the + * last -synchronize. + */ - (void) setPersistentDomain: (NSDictionary*)domain forName: (NSString*)domainName; + +/** + * Ensures that the in-memory and on-disk representations of the defaults + * are in sync. You may call this yourself, but probably don't need to + * since it is invoked at intervals whenever a runloop is running.
+ * If any persistent domain is changed by reading new values from disk, + * an NSUserDefaultsDidChangeNotification is posted. + */ - (BOOL) synchronize; -/* Maintaining Volatile Domains */ +/** + * Removes the volatile domain specified by domainName from the + * user defaults. + */ - (void) removeVolatileDomainForName: (NSString*)domainName; + +/** + * Sets the volatile-domain specified by domainName to + * domain ... a dictionary containing keys and defaults values.
+ * Raises an NSInvalidArgumentException if domainName already + * exists as either a volatile-domain or a persistent-domain. + */ - (void) setVolatileDomain: (NSDictionary*)domain forName: (NSString*)domainName; + +/** + * Returns the volatile domain specified by domainName. + */ - (NSDictionary*) volatileDomainForName: (NSString*)domainName; + +/** + * Returns an array listing the name of all the volatile domains. + */ - (NSArray*) volatileDomainNames; -/* Making Advanced Use of Defaults */ +/** + * Returns a dictionary representing the current state of the defaults + * system ... this is a merged version of all the domains in the + * search list. + */ - (NSDictionary*) dictionaryRepresentation; + +/** + * Merges the contents of the dictionary newVals into the registration + * domain. Registration defaults may be added to or replaced using this + * method, but may never be removed. Thus, setting registration defaults + * at any point in your program guarantees that the defaults will be + * available thereafter. + */ - (void) registerDefaults: (NSDictionary*)newVals; @end +#if defined(__cplusplus) +} +#endif + #endif /* __NSUserDefaults_h_OBJECTS_INCLUDE */ diff --git a/Headers/Foundation/NSUtilities.h b/Headers/Foundation/NSUtilities.h index 898be54ae..e5c00095a 100644 --- a/Headers/Foundation/NSUtilities.h +++ b/Headers/Foundation/NSUtilities.h @@ -18,16 +18,16 @@ 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., 51 Franklin Street, Fifth Floor, Boston, - MA 02111 USA. + Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02111 USA. */ #ifndef __NSUtilties_h_GNUSTEP_BASE_INCLUDE #define __NSUtilties_h_GNUSTEP_BASE_INCLUDE -#include -#include -#include -#include +#import +#import +#import +#import #endif /* __NSUtilties_h_GNUSTEP_BASE_INCLUDE */ diff --git a/Headers/Foundation/NSValue.h b/Headers/Foundation/NSValue.h index 350cadb0b..91f5f4e08 100644 --- a/Headers/Foundation/NSValue.h +++ b/Headers/Foundation/NSValue.h @@ -18,15 +18,21 @@ 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., 51 Franklin Street, Fifth Floor, Boston, - MA 02111 USA. + Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02111 USA. */ #ifndef __NSValue_h_GNUSTEP_BASE_INCLUDE #define __NSValue_h_GNUSTEP_BASE_INCLUDE +#import -#include -#include +#import +#import +#import + +#if defined(__cplusplus) +extern "C" { +#endif @class NSString; @@ -90,7 +96,7 @@ */ + (NSValue*) valueWithSize: (NSSize)size; -#ifndef STRICT_OPENSTEP +#if OS_API_VERSION(GS_API_MACOSX, GS_API_LATEST) /** * Synonym for value:withObjCType: . */ @@ -106,7 +112,7 @@ * both contents and declared type of the two values must match. */ - (BOOL) isEqualToValue: (NSValue*)other; -#endif +#endif /* GS_API_MACOSX */ // Accessing Data @@ -318,7 +324,7 @@ - (BOOL) isEqualToNumber: (NSNumber*)otherNumber; @end -#ifndef NO_GNUSTEP +#if OS_API_VERSION(GS_API_NONE, GS_API_NONE) /** * GNUstep specific (non-standard) additions to the NSNumber class. @@ -363,4 +369,8 @@ GSNumberInfo *GSNumberInfoFromObject(NSNumber *o); unsigned GSSmallHash(int n); #endif +#if defined(__cplusplus) +} +#endif + #endif /* __NSValue_h_GNUSTEP_BASE_INCLUDE */ diff --git a/Headers/Foundation/NSValueTransformer.h b/Headers/Foundation/NSValueTransformer.h new file mode 100644 index 000000000..21724943a --- /dev/null +++ b/Headers/Foundation/NSValueTransformer.h @@ -0,0 +1,119 @@ +/* Interface for NSValueTransformer for GNUStep + Copyright (C) 2006 Free Software Foundation, Inc. + + Written Dr. H. Nikolaus Schaller + Created on Mon Mar 21 2005. + Updatesd and documented by Richard Frith-Macdonald + + 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., 51 Franklin Street, Fifth Floor, + Boston, MA 02111 USA. + */ + +#ifndef __NSValueTransformer_h_GNUSTEP_BASE_INCLUDE +#define __NSValueTransformer_h_GNUSTEP_BASE_INCLUDE +#import + +#if OS_API_VERSION(100300,GS_API_LATEST) && GS_API_VERSION(010200,GS_API_LATEST) + +#import + +#if defined(__cplusplus) +extern "C" { +#endif + +@class NSArray; +@class NSString; + +/** This transformer converts a YES to a NO and a NO to a YES. + */ +GS_EXPORT NSString* const NSNegateBooleanTransformerName; + +/** This transformer converts a nil value to a YES.
+ * Not reversible. + */ +GS_EXPORT NSString* const NSIsNilTransformerName; + +/** This transformer converts a non-nil value to a YES.
+ * Not reversible. + */ +GS_EXPORT NSString* const NSIsNotNilTransformerName; + +/** This transformer converts an [NSData] instance to the object + * archived in it, or archives an object inot an [NSData]. + */ +GS_EXPORT NSString* const NSUnarchiveFromDataTransformerName; + +/** Instances of the NSValueTransformer class are used to convert + * values from one representation to another. The base class is + * abstract and its methods must be overridden by subclasses to do + * the actual work. + */ +@interface NSValueTransformer : NSObject + +/** + * Returns a flag indicating whether the transformer permits reverse + * transformations. + */ ++ (BOOL) allowsReverseTransformation; + +/** + * Registers transformer to handle transformations with the specified + * name. + */ ++ (void) setValueTransformer: (NSValueTransformer *)transformer + forName: (NSString *)name; + +/** + * Returns the class of the value produced by this transformer. + */ ++ (Class) transformedValueClass; + +/** + * Returns the transformer registered for the specified name, or nil + * if no transformer is registered for name. + */ ++ (NSValueTransformer *) valueTransformerForName: (NSString *)name; + +/** + * Returns an array listing the names of all registered value transformers. + */ ++ (NSArray *) valueTransformerNames; + +/** + * Performs a reverse transformation on the specified value and returns the + * resulting object.
+ * The default implementation raises an exception if + * +allowsReverseTransformation returns NO, otherwise it calls + * -transformedValue: and returns the result. + */ +- (id) reverseTransformedValue: (id)value; + +/** + * Subclasses should override this method to perform the actual transformation + * (and reverse transformation if applicable) and return the result. + */ +- (id) transformedValue: (id)value; + +@end + +#if defined(__cplusplus) +} +#endif + +#endif /* OS_API_VERSION */ + +#endif /* __NSValueTransformer_h_GNUSTEP_BASE_INCLUDE */ diff --git a/Headers/Foundation/NSXMLParser.h b/Headers/Foundation/NSXMLParser.h index 582b2a14d..178c9b6f9 100644 --- a/Headers/Foundation/NSXMLParser.h +++ b/Headers/Foundation/NSXMLParser.h @@ -26,10 +26,15 @@ #ifndef __NSXMLParser_h_GNUSTEP_BASE_INCLUDE #define __NSXMLParser_h_GNUSTEP_BASE_INCLUDE +#import -#ifndef STRICT_OPENSTEP +#if OS_API_VERSION(100300, GS_API_LATEST) -#include +#import + +#if defined(__cplusplus) +extern "C" { +#endif @class NSData, NSDictionary, NSError, NSString, NSURL; @@ -399,5 +404,10 @@ typedef enum { NSXMLParserDelegateAbortedParseError = 512 } NSXMLParserError; -#endif /* STRICT_OPENSTEP */ -#endif /* __NSXMLParser_h_GNUSTEP_BASE_INCLUDE*/ +#if defined(__cplusplus) +} +#endif + +#endif +#endif /* __NSXMLParser_h_GNUSTEP_BASE_INCLUDE */ + diff --git a/Headers/Foundation/NSZone.h b/Headers/Foundation/NSZone.h index e3a9da929..c7d98e257 100644 --- a/Headers/Foundation/NSZone.h +++ b/Headers/Foundation/NSZone.h @@ -18,8 +18,8 @@ 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., 51 Franklin Street, Fifth Floor, Boston, - MA 02111 USA. + Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02111 USA. AutogsdocSource: NSZone.m AutogsdocSource: NSPage.m @@ -28,6 +28,7 @@ #ifndef __NSZone_h_GNUSTEP_BASE_INCLUDE #define __NSZone_h_GNUSTEP_BASE_INCLUDE +#import /** * Primary structure representing an NSZone. Technically it @@ -53,10 +54,14 @@ */ typedef struct _NSZone NSZone; -#include +#import @class NSString; +#if defined(__cplusplus) +extern "C" { +#endif + /** * NSZoneStats is the structure returned by the NSZoneStats() @@ -242,7 +247,7 @@ GS_ZONE_SCOPE NSString* NSZoneName (NSZone *zone) return nil; } -#ifndef NO_GNUSTEP +#if OS_API_VERSION(GS_API_NONE, GS_API_NONE) /** * Allocates mmemory of size bytes from zone, with the assumption that the @@ -383,7 +388,7 @@ GS_ZONE_SCOPE NSString* NSZoneName (NSZone *zone) return zone->name; } -#ifndef NO_GNUSTEP +#if OS_API_VERSION(GS_API_NONE, GS_API_NONE) GS_ZONE_SCOPE void* NSZoneMallocAtomic (NSZone *zone, size_t size) GS_ZONE_ATTR; @@ -424,7 +429,7 @@ GS_ZONE_SCOPE struct NSZoneStats NSZoneStats (NSZone *zone) zone = NSDefaultMallocZone(); return (zone->stats)(zone); } -#endif /* NO_GNUSTEP */ +#endif /* GS_API_NONE */ #endif /* GS_WITH_GC */ @@ -447,4 +452,8 @@ GS_EXPORT void NSDeallocateMemoryPages (void *ptr, unsigned bytes); GS_EXPORT void NSCopyMemoryPages (const void *src, void *dest, unsigned bytes); +#if defined(__cplusplus) +} +#endif + #endif /* not __NSZone_h_GNUSTEP_BASE_INCLUDE */ diff --git a/INSTALL b/INSTALL index 221dd01c3..da32ac4cb 100644 --- a/INSTALL +++ b/INSTALL @@ -1,7 +1,3 @@ - ftp.gnustep.org - - pub/daily-snapshots - 0.1 Introduction ================ diff --git a/Makefile.postamble b/Makefile.postamble index e477a1638..4a9c6be8d 100644 --- a/Makefile.postamble +++ b/Makefile.postamble @@ -38,13 +38,13 @@ # Things to do after compiling # after-all:: -$(INSTALL_ROOT_DIR)$(GNUSTEP_MAKEFILES)/Additional: - $(ECHO_CREATING)$(MKDIRS) $(INSTALL_ROOT_DIR)$(GNUSTEP_MAKEFILES)/Additional$(END_ECHO) +$(DESTDIR)$(GNUSTEP_MAKEFILES)/Additional: + $(ECHO_CREATING)$(MKDIRS) $(DESTDIR)$(GNUSTEP_MAKEFILES)/Additional$(END_ECHO) # Things to do before installing -before-install:: $(INSTALL_ROOT_DIR)$(GNUSTEP_MAKEFILES)/Additional +before-install:: $(DESTDIR)$(GNUSTEP_MAKEFILES)/Additional $(ECHO_NOTHING)$(INSTALL_DATA) base.make \ - $(INSTALL_ROOT_DIR)$(GNUSTEP_MAKEFILES)/Additional/base.make$(END_ECHO) + $(DESTDIR)$(GNUSTEP_MAKEFILES)/Additional/base.make$(END_ECHO) # Things to do after installing # after-install:: @@ -54,7 +54,8 @@ before-install:: $(INSTALL_ROOT_DIR)$(GNUSTEP_MAKEFILES)/Additional # Things to do after uninstalling after-uninstall:: - $(ECHO_NOTHING)rm -f $(INSTALL_ROOT_DIR)$(GNUSTEP_MAKEFILES)/Additional/base.make$(END_ECHO) + $(ECHO_NOTHING)rm -f $(DESTDIR)$(GNUSTEP_MAKEFILES)/Additional/base.make$(END_ECHO) + # Things to do before cleaning # before-clean:: diff --git a/NEWS b/NEWS index 2c92c5930..4125b7304 100644 --- a/NEWS +++ b/NEWS @@ -1,15 +1,19 @@ - ftp.gnustep.org - - pub/daily-snapshots - 1 News ****** -The currently released version of the library is `1.13.1'. +The currently released version of the library is `1.14.0'. - See the `ReleaseNotes.html' document for more information. +See the `ReleaseNotes.html' document for more information. -1.1 Noteworthy changes in version `1.13.1' +1.1 Noteworthy changes in version `1.14.0' +========================================== + +Many portability (particularly for ms-windows) and MacOS-X +compatibility fixes. New MacOS-X classes and incorporation of +NSAffineTransform and NSSpellServer which were formerly in the gui +library. Improved performance of amssively multithreaded programs. + +1.2 Noteworthy changes in version `1.13.1' ========================================== Various minor bugs and MacOS-X incompatibilities fixed. One important @@ -18,13 +22,13 @@ objects from strings. One fix for a serious (crash) bug when initialising the bundles system in an application which has a lot of frameworks linked to it. See the release notes for more details. -1.2 Noteworthy changes in version `1.13.0' +1.3 Noteworthy changes in version `1.13.0' ========================================== Several sets of classes have been added for dealing with urls and predicates. A few minor api changes have occured as well. -1.3 Noteworthy changes in version `1.12.0' +1.4 Noteworthy changes in version `1.12.0' ========================================== There have been a number of API changes and several methods have been @@ -40,7 +44,7 @@ can be set to not write to an external file at all, for developers who wish to use the library as a stand-alone library or in other situations where using external resources is not desired. -1.4 Noteworthy changes in version `1.11.2' +1.5 Noteworthy changes in version `1.11.2' ========================================== * Support for GNUstep.conf and relocation of the filesystem is much @@ -57,7 +61,7 @@ where using external resources is not desired. * Some support for keeping user defaults in the Windows registry implemented. -1.5 Noteworthy changes in version `1.11.1' +1.6 Noteworthy changes in version `1.11.1' ========================================== * New Cocoa class NSSortDescriptor @@ -69,7 +73,7 @@ where using external resources is not desired. * More support for debugging on mingw, including writing logs to debugger and event viewer. -1.6 Noteworthy changes in version `1.11.0' +1.7 Noteworthy changes in version `1.11.0' ========================================== This release is binary incompatible with previous releases. The @@ -88,12 +92,12 @@ new version. * NSRunLoop and related classes use natvie win32 event handling on Windows machines. -1.7 Noteworthy changes in version `1.10.3' +1.8 Noteworthy changes in version `1.10.3' ========================================== This version includes a few minor bug fixes. -1.8 Noteworthy changes in version `1.10.2' +1.9 Noteworthy changes in version `1.10.2' ========================================== This version mostly includes minor fixes and updates. @@ -107,8 +111,8 @@ This version mostly includes minor fixes and updates. * Use a proper one-to-one abbreviation dictionary for NSTimeZone. -1.9 Noteworthy changes in version `1.10.1' -========================================== +1.10 Noteworthy changes in version `1.10.1' +=========================================== This version mostly includes minor fixes and updates. @@ -122,7 +126,7 @@ This version mostly includes minor fixes and updates. * Designated initializers for NSArray, NSDictionary, NSSet, and NSString have been changed for MacOS X compatibility. -1.10 Noteworthy changes in version `1.10.0' +1.11 Noteworthy changes in version `1.10.0' =========================================== Note the interface version of the library has changed so that apps, @@ -136,7 +140,7 @@ use it. * Mac OSX XML compatibility fixes. -1.11 Noteworthy changes in version `1.9.2' +1.12 Noteworthy changes in version `1.9.2' ========================================== * GSMime parsing ignores extraneous data @@ -154,7 +158,7 @@ use it. * Binary incompatibility: NSUnarchiver, GSIMapTable have new ivars added -1.12 Noteworthy changes in version `1.9.1' +1.13 Noteworthy changes in version `1.9.1' ========================================== * Default string encoding taken from system nl_langinfo if not set @@ -165,7 +169,7 @@ use it. * NSPropertyLists class added, also decodes Mac OS X binary propery lists. -1.13 Noteworthy changes in version `1.9.0' +1.14 Noteworthy changes in version `1.9.0' ========================================== * Lazy locking implemented (see GSLock documentation) @@ -182,7 +186,7 @@ use it. * NSString subclass heirarchy reorganized to fix problems with copying and ownership of data. -1.14 Noteworthy changes in version `1.8.0' +1.15 Noteworthy changes in version `1.8.0' ========================================== Read the NEWS file for a complete list of changes since the last stable @@ -192,14 +196,14 @@ changes in gnustep-make, several components of gnustep-base are located in different locations. Generally this should not affect the compilation or running of applications and tools. -1.15 Noteworthy changes in version `1.7.4' +1.16 Noteworthy changes in version `1.7.4' ========================================== * Added Korean encoding * Updated use of ObjCRuntime functions. -1.16 Noteworthy changes in version `1.7.3' +1.17 Noteworthy changes in version `1.7.3' ========================================== Note in this version there have been large changes to the location of @@ -211,7 +215,7 @@ specific headers may not compile because of this. * New TraditionalChinese language. -1.17 Noteworthy changes in version `1.7.2' +1.18 Noteworthy changes in version `1.7.2' ========================================== * NSUndoManager improvements @@ -222,12 +226,12 @@ specific headers may not compile because of this. * Improvements to handle selectors better over remote connections. -1.18 Noteworthy changes in version `1.7.1' +1.19 Noteworthy changes in version `1.7.1' ========================================== Bug fixes. -1.19 Noteworthy changes in version `1.7.0' +1.20 Noteworthy changes in version `1.7.0' ========================================== See gnustep-make for comments on the filesystem change. Some components @@ -244,7 +248,7 @@ changes: * Added man page for gdomap -1.20 Noteworthy changes in version `1.6.0' +1.21 Noteworthy changes in version `1.6.0' ========================================== * More MinGW support @@ -259,7 +263,7 @@ changes: * Any many many bug fixes and minor improvements. -1.21 Noteworthy changes in version `1.5.1' +1.22 Noteworthy changes in version `1.5.1' ========================================== * Port NSThread to MingW @@ -278,7 +282,7 @@ changes: * NSTimeZone code rewritten for speed. -1.22 Noteworthy changes in version `1.5.0' +1.23 Noteworthy changes in version `1.5.0' ========================================== * New MacOSX methods implemented (NSString, NSArray, NSObject) @@ -287,12 +291,12 @@ changes: * Tcp connections use runloop in NSConnectionReplyMode. -1.23 Noteworthy changes in version `1.4.0' +1.24 Noteworthy changes in version `1.4.0' ========================================== * gdomap - security bug fixes. -1.24 Noteworthy changes in version `1.3.4' +1.25 Noteworthy changes in version `1.3.4' ========================================== This is a first pre-release version for 1.4. @@ -304,7 +308,7 @@ users are urged to upgrade to this version as soon as possible. * New combined Unix/Windows version of NSFileHandle -1.25 Noteworthy changes in version `1.3.3' +1.26 Noteworthy changes in version `1.3.3' ========================================== Note there are interface and binary changes in this release that @@ -325,7 +329,7 @@ gnustep-base. * Support for system-wide .GNUsteprc -1.26 Noteworthy changes in version `1.3.2' +1.27 Noteworthy changes in version `1.3.2' ========================================== * Corrections for handling Windows file paths, etc @@ -343,7 +347,7 @@ gnustep-base. * Unicode and UTF8 handling improvements. -1.27 Noteworthy changes in version `1.3.0' +1.28 Noteworthy changes in version `1.3.0' ========================================== * Moved additional classes into subprojects and/or bundles to make it @@ -359,7 +363,7 @@ gnustep-base. * New, partially finished Objective-C/Foundation programming manual. -1.28 Noteworthy changes in version `1.1.0' +1.29 Noteworthy changes in version `1.1.0' ========================================== * Removed use of distributed lock to sync defaults file. @@ -381,7 +385,7 @@ gnustep-base. * XML property lists -1.29 Noteworthy changes in version `1.0.2' +1.30 Noteworthy changes in version `1.0.2' ========================================== Mostly a bug fix release to work with the new gcc 3.0. @@ -389,7 +393,7 @@ Mostly a bug fix release to work with the new gcc 3.0. * Added support for special gcc 3.0 options (constant string support). -1.30 Noteworthy changes in version `1.0.1' +1.31 Noteworthy changes in version `1.0.1' ========================================== * Many fixes to work better with Darwin (still not there). @@ -405,7 +409,7 @@ Mostly a bug fix release to work with the new gcc 3.0. * More memory debugging support. -1.31 Noteworthy changes in version `1.0.0' +1.32 Noteworthy changes in version `1.0.0' ========================================== * Fix parsing of arguments for new linux kernels. @@ -416,7 +420,7 @@ Mostly a bug fix release to work with the new gcc 3.0. * Update unicode support and fixes -1.32 Noteworthy changes in version `0.9.1' +1.33 Noteworthy changes in version `0.9.1' ========================================== * New MacOSX compatible files for NSCalendarDate, NSTimeZone @@ -429,7 +433,7 @@ Mostly a bug fix release to work with the new gcc 3.0. * Added some gettext compatible localization macros. -1.33 Noteworthy changes in version `0.9.1' +1.34 Noteworthy changes in version `0.9.1' ========================================== * Fixes for building on FreeBSD @@ -440,7 +444,7 @@ Mostly a bug fix release to work with the new gcc 3.0. * Updated for Makefile package changes. -1.34 Noteworthy changes in version `0.9.0' +1.35 Noteworthy changes in version `0.9.0' ========================================== * Workaround when no host IP set. @@ -478,7 +482,7 @@ Mostly a bug fix release to work with the new gcc 3.0. * Removed obsolete classes. -1.35 Noteworthy changes in version `0.6.6' +1.36 Noteworthy changes in version `0.6.6' ========================================== * Lots of new documentation. @@ -495,7 +499,7 @@ Mostly a bug fix release to work with the new gcc 3.0. * More optimization of classes. -1.36 Noteworthy changes in version `0.6.5' +1.37 Noteworthy changes in version `0.6.5' ========================================== * Better debugging information. @@ -509,7 +513,7 @@ Mostly a bug fix release to work with the new gcc 3.0. * Lots of optimizations and bug fixes. -1.37 Noteworthy changes in version `0.6.0' +1.38 Noteworthy changes in version `0.6.0' ========================================== Most of the changes to the Base Library are bug fixes and updates to @@ -525,7 +529,7 @@ and installations, and is considered to be fairly stable. * Performance boosts in many classes. -1.38 Noteworthy changes in version `0.5.5' +1.39 Noteworthy changes in version `0.5.5' ========================================== Too many changes to mention in detail, but here is a list of a few: @@ -544,14 +548,14 @@ Too many changes to mention in detail, but here is a list of a few: pasteboards. -1.39 Noteworthy changes in version `0.5.1' +1.40 Noteworthy changes in version `0.5.1' ========================================== * Additional runtime functions for interaction with Guile and ObjC-Guile library. -1.40 Noteworthy changes in version `0.5.0' +1.41 Noteworthy changes in version `0.5.0' ========================================== * Improvements to the NSInvocation class, from Masatake Yamato @@ -566,7 +570,7 @@ Too many changes to mention in detail, but here is a list of a few: . -1.41 Noteworthy changes in version `0.4.0' +1.42 Noteworthy changes in version `0.4.0' ========================================== * New tools for maintaining the defaults database. @@ -601,7 +605,7 @@ Too many changes to mention in detail, but here is a list of a few: * Many, many, many, many bug fixes and new classes. -1.42 Noteworthy changes since version `0.1.19' +1.43 Noteworthy changes since version `0.1.19' ============================================== * The library has changed its name from `libobjects' to @@ -703,7 +707,7 @@ Too many changes to mention in detail, but here is a list of a few: * ...and many bug fixes. -1.43 Noteworthy changes since version `0.1.14' +1.44 Noteworthy changes since version `0.1.14' ============================================== * Can be made as a shared library by passing `--enabled-shared' to @@ -738,7 +742,7 @@ Too many changes to mention in detail, but here is a list of a few: places. -1.44 Noteworthy changes since version `0.1.13' +1.45 Noteworthy changes since version `0.1.13' ============================================== * NSProcessInfo class, thanks to Georg Tuparev. @@ -753,7 +757,7 @@ Too many changes to mention in detail, but here is a list of a few: * Many bug fixes. -1.45 Noteworthy changes since version `0.1.12' +1.46 Noteworthy changes since version `0.1.12' ============================================== * Bug fixes: installation; NSArray and NSDictionary copying; @@ -762,7 +766,7 @@ Too many changes to mention in detail, but here is a list of a few: ChangeLog for more details. -1.46 Noteworthy changes since version `0.1.10' +1.47 Noteworthy changes since version `0.1.10' ============================================== * Now using `src', `config' and `doc' directories to un-clutter the @@ -780,7 +784,7 @@ Too many changes to mention in detail, but here is a list of a few: * And several bug fixes. See the ChangeLog for details. -1.47 Noteworthy changes since version `0.1.9' +1.48 Noteworthy changes since version `0.1.9' ============================================= * Renamed "foundation" include file directory to "Foundation", in @@ -790,7 +794,7 @@ Too many changes to mention in detail, but here is a list of a few: 0.1.9. -1.48 Noteworthy changes since version `0.1.8' +1.49 Noteworthy changes since version `0.1.8' ============================================= * Many new GNUStep classes: NSEnumerator, NSArrayEnumerator, NSCoder, @@ -827,7 +831,7 @@ Too many changes to mention in detail, but here is a list of a few: implementations back in Collection.m. -1.49 Noteworthy changes since version `0.1.7' +1.50 Noteworthy changes since version `0.1.7' ============================================= * Thanks to Adam Fedor , classes @@ -849,7 +853,7 @@ Too many changes to mention in detail, but here is a list of a few: deallocation and behavior adding. See the ChangeLog for details. -1.50 Noteworthy changes since version `0.1.5' +1.51 Noteworthy changes since version `0.1.5' ============================================= * Better string handling. NSString is now fleshed out, and I've @@ -877,7 +881,7 @@ Too many changes to mention in detail, but here is a list of a few: are in the ChangeLog. -1.51 Noteworthy changes since version `0.1.3' +1.52 Noteworthy changes since version `0.1.3' ============================================= This release not well tested at all. We desperately need someone to @@ -904,7 +908,7 @@ made on GNUSTEP. `autorelease', `dealloc' instead of `free'. -1.52 Noteworthy changes since version `0.1.0' +1.53 Noteworthy changes since version `0.1.0' ============================================= * New category: ObjectRetaining. New classes: AutoreleasePool, @@ -914,7 +918,7 @@ made on GNUSTEP. README.ULTRIX. Time.m patched for Solaris 2.4. test12.m free fix. -1.53 Noteworthy changes in version `0.1.0' +1.54 Noteworthy changes in version `0.1.0' ========================================== * Renamed the library from `libcoll' to `libgnustep-base'. (See the @@ -948,7 +952,7 @@ made on GNUSTEP. for NeXT-compatible zone functions. -1.54 Noteworthy changes in verion `940524' +1.55 Noteworthy changes in verion `940524' ========================================== * A NeXT-compatible NXStringTable object, thanks to Adam Fedor @@ -975,7 +979,7 @@ made on GNUSTEP. for better NeXT-compability. And more. -1.55 Noteworthy changes in version `931026' +1.56 Noteworthy changes in version `931026' =========================================== * Installation using `./configure' and `autoconf' diff --git a/NSCharacterSets/GNUmakefile b/NSCharacterSets/GNUmakefile index 80f441746..800d83e59 100644 --- a/NSCharacterSets/GNUmakefile +++ b/NSCharacterSets/GNUmakefile @@ -21,10 +21,19 @@ # Software Foundation, Inc., 51 Franklin Street, Fifth Floor, # Boston, MA 02111 USA. +ifeq ($(GNUSTEP_MAKEFILES),) + GNUSTEP_MAKEFILES := $(shell gnustep-config --variable=GNUSTEP_MAKEFILES 2>/dev/null) +endif + +ifeq ($(GNUSTEP_MAKEFILES),) + $(error You need to set GNUSTEP_MAKEFILES before compiling!) +endif + # Install into the system root by default -GNUSTEP_INSTALLATION_DIR = $(GNUSTEP_SYSTEM_ROOT) +GNUSTEP_INSTALLATION_DOMAIN = SYSTEM GNUSTEP_LOCAL_ADDITIONAL_MAKEFILES=../base.make + include $(GNUSTEP_MAKEFILES)/common.make CHARSET_FILES = \ diff --git a/NSTimeZones/GNUmakefile b/NSTimeZones/GNUmakefile index 627e6f613..60c3849f5 100644 --- a/NSTimeZones/GNUmakefile +++ b/NSTimeZones/GNUmakefile @@ -18,18 +18,30 @@ # # 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., 51 Franklin Street, Fifth Floor, Boston, MA 02111 USA. +# Software Foundation, Inc., 51 Franklin Street, Fifth Floor, +# Boston, MA 02111 USA. + +ifeq ($(GNUSTEP_MAKEFILES),) + GNUSTEP_MAKEFILES := $(shell gnustep-config --variable=GNUSTEP_MAKEFILES 2>/dev/null) +endif + +ifeq ($(GNUSTEP_MAKEFILES),) + $(error You need to set GNUSTEP_MAKEFILES before compiling!) +endif # Install into the system root by default -GNUSTEP_INSTALLATION_DIR = $(GNUSTEP_SYSTEM_ROOT) +GNUSTEP_INSTALLATION_DOMAIN = SYSTEM GNUSTEP_LOCAL_ADDITIONAL_MAKEFILES=../base.make + include $(GNUSTEP_MAKEFILES)/common.make include ../Version include ../config.mak -resourcedir = $(GNUSTEP_RESOURCES)/gnustep-base +libgnustep-base_INTERFACE_VERSION=$(MAJOR_VERSION).$(MINOR_VERSION) + +resourcedir = $(GNUSTEP_LIBRARY)/Libraries/gnustep-base/Versions/$(libgnustep-base_INTERFACE_VERSION)/Resources TIMEZONE_ARCHIVE = \ NSTimeZones.tar diff --git a/NSTimeZones/NSTimeZones.tar b/NSTimeZones/NSTimeZones.tar index d2aa6b956..52acaf444 100644 Binary files a/NSTimeZones/NSTimeZones.tar and b/NSTimeZones/NSTimeZones.tar differ diff --git a/README b/README index 98c182280..00393a9b9 100644 --- a/README +++ b/README @@ -1,18 +1,13 @@ 1 Readme ******** - ftp.gnustep.org +The GNUstep Base Library is a library of general-purpose, non-graphical +Objective C objects. For example, it includes classes for strings, +object collections, byte streams, typed coders, invocations, +notifications, notification dispatchers, moments in time, network ports, +remote object messaging support (distributed objects), and event loops. - pub/daily-snapshots - - The GNUstep Base Library is a library of general-purpose, -non-graphical Objective C objects. For example, it includes classes -for strings, object collections, byte streams, typed coders, -invocations, notifications, notification dispatchers, moments in time, -network ports, remote object messaging support (distributed objects), -and event loops. - - It provides functionality that aims to implement the non-graphical +It provides functionality that aims to implement the non-graphical portion of the OpenStep standard (the Foundation library). 1.1 Initial reading diff --git a/Resources/GNUmakefile b/Resources/GNUmakefile index 450813c7e..99ddc7803 100644 --- a/Resources/GNUmakefile +++ b/Resources/GNUmakefile @@ -19,15 +19,31 @@ # # 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., 51 Franklin Street, Fifth Floor, Boston, MA 02111 USA. +# Software Foundation, Inc., 51 Franklin Street, Fifth Floor, +# Boston, MA 02111 USA. -GNUSTEP_INSTALLATION_DIR = $(GNUSTEP_SYSTEM_ROOT) +ifeq ($(GNUSTEP_MAKEFILES),) + GNUSTEP_MAKEFILES := $(shell gnustep-config --variable=GNUSTEP_MAKEFILES 2>/dev/null) +endif + +ifeq ($(GNUSTEP_MAKEFILES),) + $(error You need to set GNUSTEP_MAKEFILES before compiling!) +endif + +GNUSTEP_INSTALLATION_DOMAIN = SYSTEM GNUSTEP_LOCAL_ADDITIONAL_MAKEFILES=../base.make + include $(GNUSTEP_MAKEFILES)/common.make +include ../Version +libgnustep-base_INTERFACE_VERSION=$(MAJOR_VERSION).$(MINOR_VERSION) + RESOURCE_SET_NAME = base-resources -base-resources_RESOURCE_FILES_INSTALL_DIR = Library/Libraries/Resources/gnustep-base +# This is for gnustep-make >= 14-02-2007 +base-resources_INSTALL_DIR = $(GNUSTEP_LIBRARY)/Libraries/gnustep-base/Versions/$(libgnustep-base_INTERFACE_VERSION)/Resources +# This is kept temporarily for gnustep-make < 14-02-2007 +base-resources_RESOURCE_FILES_INSTALL_DIR = /Library/Libraries/Resources/gnustep-base base-resources_LANGUAGES = English German French Italian TraditionalChinese \ Spanish Esperanto Korean base-resources_LOCALIZED_RESOURCE_FILES = Localizable.strings diff --git a/SSL/GNUmakefile b/SSL/GNUmakefile index a4c264d71..9fd586799 100644 --- a/SSL/GNUmakefile +++ b/SSL/GNUmakefile @@ -19,18 +19,25 @@ # # 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., 51 Franklin Street, Fifth Floor, Boston, MA 02111 USA. +# Software Foundation, Inc., 51 Franklin Street, Fifth Floor, +# Boston, MA 02111 USA. # +ifeq ($(GNUSTEP_MAKEFILES),) + GNUSTEP_MAKEFILES := $(shell gnustep-config --variable=GNUSTEP_MAKEFILES 2>/dev/null) +endif + +ifeq ($(GNUSTEP_MAKEFILES),) + $(error You need to set GNUSTEP_MAKEFILES before compiling!) +endif + # Install into the system root by default -GNUSTEP_INSTALLATION_DIR = $(GNUSTEP_SYSTEM_ROOT) +GNUSTEP_INSTALLATION_DOMAIN = SYSTEM # This must set be before reading common.make, which will read the # Additional makefiles. GNUSTEP_LOCAL_ADDITIONAL_MAKEFILES=../base.make -# Include common.make as the first thing, as this defined -# FOUNDATION_LIB which is used in ../config.mak include $(GNUSTEP_MAKEFILES)/common.make -include ../config.mak @@ -45,6 +52,11 @@ ifeq ($(HAVE_OPENSSL), yes) # The bundles to be compiled BUNDLE_NAME=SSL +# Interface version changes with each minor release +include ../Version +libgnustep-base_INTERFACE_VERSION=$(MAJOR_VERSION).$(MINOR_VERSION) +SSL_INSTALL_DIR = $(GNUSTEP_LIBRARY)/Libraries/gnustep-base/Versions/$(libgnustep-base_INTERFACE_VERSION)/Resources/ + # Additional search directories for linking SSL_LIB_DIRS += -L$(GNUSTEP_OBJ_DIR) diff --git a/SSL/GSSSLHandle.m b/SSL/GSSSLHandle.m index 856de0af8..de7837f90 100644 --- a/SSL/GSSSLHandle.m +++ b/SSL/GSSSLHandle.m @@ -18,7 +18,8 @@ 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., 51 Franklin Street, Fifth Floor, Boston, MA 02111 USA. + Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02111 USA. */ @@ -49,10 +50,10 @@ #include #undef id -#include #include #include +#include "GSPrivate.h" #if defined(__MINGW32__) #include @@ -78,10 +79,9 @@ #ifdef HAVE_UNISTD_H #include #endif -#include static NSString* -sslError(int err, int e) +sslError(int err) { NSString *str; @@ -105,8 +105,12 @@ sslError(int err, int e) str = @"Want X509 Lookup Error"; break; case SSL_ERROR_SYSCALL: - str = [NSString stringWithFormat: @"Syscall error %d - %s", - e, GSLastErrorStr(e)]; + { + NSError *e = [NSError _last]; + + str = [NSString stringWithFormat: @"Syscall error %d - %@", + [e code], [e description]]; + } break; case SSL_ERROR_SSL: str = @"SSL Error: really helpful"; @@ -222,7 +226,6 @@ sslError(int err, int e) } if (ret != 1) { - int e = errno; NSDate *final; NSDate *when; NSTimeInterval last = 0.0; @@ -251,7 +254,6 @@ sslError(int err, int e) ret = SSL_accept(ssl); if (ret != 1) { - e = errno; err = SSL_get_error(ssl, ret); } else @@ -269,7 +271,7 @@ sslError(int err, int e) * Some other error ... not just a timeout or disconnect */ NSLog(@"unable to accept SSL connection from %@:%@ - %@", - address, service, sslError(err, e)); + address, service, sslError(err)); ERR_print_errors_fp(stderr); } @@ -328,7 +330,6 @@ sslError(int err, int e) } if (ret != 1) { - int e = errno; NSDate *final; NSDate *when; NSTimeInterval last = 0.0; @@ -357,7 +358,6 @@ sslError(int err, int e) ret = SSL_connect(ssl); if (ret != 1) { - e = errno; err = SSL_get_error(ssl, ret); } else @@ -369,13 +369,14 @@ sslError(int err, int e) RELEASE(final); if (err != SSL_ERROR_NONE) { + if (err != SSL_ERROR_WANT_READ && err != SSL_ERROR_WANT_WRITE) if (err != SSL_ERROR_WANT_READ && err != SSL_ERROR_WANT_WRITE) { /* * Some other error ... not just a timeout or disconnect */ NSLog(@"unable to make SSL connection to %@:%@ - %@", - address, service, sslError(err, e)); + address, service, sslError(err)); ERR_print_errors_fp(stderr); } RELEASE(self); @@ -437,7 +438,7 @@ sslError(int err, int e) if (ret != 1) { NSLog(@"Failed to set certificate file to %@ - %@", - certFile, sslError(ERR_get_error(), errno)); + certFile, sslError(ERR_get_error())); } } if ([privateKey length] > 0) @@ -447,7 +448,7 @@ sslError(int err, int e) if (ret != 1) { NSLog(@"Failed to set private key file to %@ - %@", - privateKey, sslError(ERR_get_error(), errno)); + privateKey, sslError(ERR_get_error())); } } } diff --git a/SSL/Makefile.postamble b/SSL/Makefile.postamble index eb9a7b605..479836236 100644 --- a/SSL/Makefile.postamble +++ b/SSL/Makefile.postamble @@ -67,7 +67,7 @@ # Things to do after distcleaning after-distclean:: - rm -rf $(GNUSTEP_TARGET_DIR)/config.h + rm -rf $(GNUSTEP_TARGET_DIR)/config.h config.status config.log config.cache TAGS config.mak config.h # Things to do before checking # before-check:: @@ -75,14 +75,20 @@ after-distclean:: # Things to do after checking # after-check:: -config.mak: config.mak.in - ./configure +config.mak: config.mak.in config.status + ./config.status # # The config.h file is specific to a target # -$(GNUSTEP_TARGET_DIR)/config.h: ../config.status +$(GNUSTEP_TARGET_DIR)/config.h: config.status + ./config.status +ifneq ($(GNUSTEP_TARGET_DIR), .) $(MKDIRS) $(GNUSTEP_TARGET_DIR) -mv config.h $(GNUSTEP_TARGET_DIR) -touch $(GNUSTEP_TARGET_DIR)/config.h +endif +# Run configure manually if you need to pass any options +config.status: + ./configure diff --git a/SSL/Makefile.preamble b/SSL/Makefile.preamble index 4b9926ba9..8b8d42b40 100644 --- a/SSL/Makefile.preamble +++ b/SSL/Makefile.preamble @@ -48,8 +48,12 @@ ADDITIONAL_OBJCFLAGS = $(SSLFLAGS) ADDITIONAL_CFLAGS = # Additional include directories the compiler should search +# FIXME - the -I../Source seems wrong because it might +# include config.h from gnustep-base instead of the +# one in this directory. It is required to find +# GSPrivate.h on non-flattened though. ADDITIONAL_INCLUDE_DIRS = -I./$(GNUSTEP_TARGET_DIR) \ - -I../Source/$(GNUSTEP_TARGET_DIR) \ + -I../Source/$(GNUSTEP_TARGET_DIR) -I../Source \ -I../Headers/Additions -I../Headers # Additional LDFLAGS to pass to the linker diff --git a/SSL/configure b/SSL/configure index b67b2efb5..face9fd36 100755 --- a/SSL/configure +++ b/SSL/configure @@ -1348,15 +1348,35 @@ ac_configure="$SHELL $ac_aux_dir/configure" # This should be Cygnus configure. #-------------------------------------------------------------------- # Miscellaneous flags #-------------------------------------------------------------------- -# Set location of GNUstep dirs for later use -GNUSTEP_HDIR=$GNUSTEP_SYSTEM_ROOT/Headers -if test "$GNUSTEP_FLATTENED" = yes; then - GNUSTEP_LDIR=$GNUSTEP_SYSTEM_ROOT/Libraries -else + +# +# It looks like we ought to source the whole GNUstep.sh here, and even +# ask it to output all variables! That way we have access to (eg) +# GNUSTEP_SYSTEM_HEADERS below. +# +GNUSTEP_SH_EXPORT_ALL_VARIABLES=yes +. "$GNUSTEP_MAKEFILES/GNUstep.sh" +unset GNUSTEP_SH_EXPORT_ALL_VARIABLES + +# For backwards compatibility, define GNUSTEP_SYSTEM_HEADERS from +# GNUSTEP_SYSTEM_ROOT if not set yet. +if test x"$GNUSTEP_SYSTEM_HEADERS" = x""; then + GNUSTEP_SYSTEM_HEADERS="$GNUSTEP_SYSTEM_ROOT/Library/Headers" +fi + +if test x"$GNUSTEP_SYSTEM_LIBRARIES" = x""; then + GNUSTEP_SYSTEM_LIBRARIES="$GNUSTEP_SYSTEM_ROOT/Library/Libraries" +fi + +if test "$GNUSTEP_IS_FLATTENED" = no; then clean_target_os=`$GNUSTEP_MAKEFILES/clean_os.sh $target_os` clean_target_cpu=`$GNUSTEP_MAKEFILES/clean_cpu.sh $target_cpu` obj_dir=$clean_target_cpu/$clean_target_os - GNUSTEP_LDIR=$GNUSTEP_SYSTEM_ROOT/Libraries/$obj_dir + GNUSTEP_LDIR=$GNUSTEP_SYSTEM_LIBRARIES/$obj_dir + GNUSTEP_HDIR=$GNUSTEP_SYSTEM_HEADERS/$LIBRARY_COMBO +else + GNUSTEP_LDIR=$GNUSTEP_SYSTEM_LIBRARIES + GNUSTEP_HDIR=$GNUSTEP_SYSTEM_HEADERS fi # diff --git a/SSL/configure.ac b/SSL/configure.ac index acada4258..9c7fe854d 100644 --- a/SSL/configure.ac +++ b/SSL/configure.ac @@ -40,15 +40,35 @@ AC_CONFIG_AUX_DIR($GNUSTEP_MAKEFILES) #-------------------------------------------------------------------- # Miscellaneous flags #-------------------------------------------------------------------- -# Set location of GNUstep dirs for later use -GNUSTEP_HDIR=$GNUSTEP_SYSTEM_ROOT/Headers -if test "$GNUSTEP_FLATTENED" = yes; then - GNUSTEP_LDIR=$GNUSTEP_SYSTEM_ROOT/Libraries -else + +# +# It looks like we ought to source the whole GNUstep.sh here, and even +# ask it to output all variables! That way we have access to (eg) +# GNUSTEP_SYSTEM_HEADERS below. +# +GNUSTEP_SH_EXPORT_ALL_VARIABLES=yes +. "$GNUSTEP_MAKEFILES/GNUstep.sh" +unset GNUSTEP_SH_EXPORT_ALL_VARIABLES + +# For backwards compatibility, define GNUSTEP_SYSTEM_HEADERS from +# GNUSTEP_SYSTEM_ROOT if not set yet. +if test x"$GNUSTEP_SYSTEM_HEADERS" = x""; then + GNUSTEP_SYSTEM_HEADERS="$GNUSTEP_SYSTEM_ROOT/Library/Headers" +fi + +if test x"$GNUSTEP_SYSTEM_LIBRARIES" = x""; then + GNUSTEP_SYSTEM_LIBRARIES="$GNUSTEP_SYSTEM_ROOT/Library/Libraries" +fi + +if test "$GNUSTEP_IS_FLATTENED" = no; then clean_target_os=`$GNUSTEP_MAKEFILES/clean_os.sh $target_os` clean_target_cpu=`$GNUSTEP_MAKEFILES/clean_cpu.sh $target_cpu` obj_dir=$clean_target_cpu/$clean_target_os - GNUSTEP_LDIR=$GNUSTEP_SYSTEM_ROOT/Libraries/$obj_dir + GNUSTEP_LDIR=$GNUSTEP_SYSTEM_LIBRARIES/$obj_dir + GNUSTEP_HDIR=$GNUSTEP_SYSTEM_HEADERS/$LIBRARY_COMBO +else + GNUSTEP_LDIR=$GNUSTEP_SYSTEM_LIBRARIES + GNUSTEP_HDIR=$GNUSTEP_SYSTEM_HEADERS fi # diff --git a/Source/Additions/GNUmakefile b/Source/Additions/GNUmakefile index 28b6276fd..d494a77d6 100644 --- a/Source/Additions/GNUmakefile +++ b/Source/Additions/GNUmakefile @@ -19,7 +19,8 @@ # # 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., 51 Franklin Street, Fifth Floor, Boston, MA 02111 USA. +# Software Foundation, Inc., 51 Franklin Street, Fifth Floor, +# Boston, MA 02111 USA. # GNUSTEP_LOCAL_ADDITIONAL_MAKEFILES=../../base.make diff --git a/Source/Additions/GSCategories.m b/Source/Additions/GSCategories.m index a2e551517..016e1b4f7 100644 --- a/Source/Additions/GSCategories.m +++ b/Source/Additions/GSCategories.m @@ -24,9 +24,10 @@ */ #include "config.h" #include -#include +#include "Foundation/Foundation.h" #include "GNUstepBase/GSCategories.h" #include "GNUstepBase/GSLock.h" +#include "GSPrivate.h" /* Test for ASCII whitespace which is safe for unicode characters */ #define space(C) ((C) > 127 ? NO : isspace(C)) @@ -899,6 +900,87 @@ static void MD5Transform (uint32_t buf[4], uint32_t const in[16]) } @end + + +/** + * GNUstep specific (non-standard) additions to the NSError class. + * Possibly to be made public + */ +@implementation NSError(GSCategories) + +#ifndef HAVE_STRERROR +static const char * +strerror(int eno) +{ + extern char *sys_errlist[]; + extern int sys_nerr; + + if (eno < 0 || eno >= sys_nerr) + { + return("unknown error number"); + } + return(sys_errlist[eno]); +} +#endif + +/* + * Returns an NSError instance encapsulating the last system error. + * The user info dictionary of this object will be mutable, so that + * additional information can be placed in it by higher level code. + */ ++ (NSError*) _last +{ +#if defined(__MINGW32__) + return [self _systemError: GetLastError()]; +#else + extern int errno; + + return [self _systemError: errno]; +#endif +} + ++ (NSError*) _systemError: (long)code +{ + NSError *error; + NSString *domain; + NSDictionary *info; +#if defined(__MINGW32__) + LPVOID lpMsgBuf; + NSString *message; + + domain = NSOSStatusErrorDomain; + FormatMessageW(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM, + NULL, code, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), + (LPWSTR) &lpMsgBuf, 0, NULL ); + message = [NSString stringWithCharacters: lpMsgBuf length: wcslen(lpMsgBuf)]; + LocalFree(lpMsgBuf); + info = [NSMutableDictionary dictionaryWithObjectsAndKeys: + message, NSLocalizedDescriptionKey, + nil]; +#else + NSString *message; + + /* FIXME ... not all are POSIX, should we use NSMachErrorDomain for some? */ + domain = NSPOSIXErrorDomain; + message = [NSString stringWithCString: strerror(code) + encoding: [NSString defaultCStringEncoding]]; + /* FIXME ... can we do better localisation? */ + info = [NSMutableDictionary dictionaryWithObjectsAndKeys: + message, NSLocalizedDescriptionKey, + nil]; +#endif + + /* NB we use a mutable dictionary so that calling code can add extra + * information to the dictionary before passing it up to higher level + * code. + */ + error = [self errorWithDomain: domain code: code userInfo: info]; + return error; +} +@end + + + /** * GNUstep specific (non-standard) additions to the NSNumber class. */ diff --git a/Source/Additions/GSCompatibility.m b/Source/Additions/GSCompatibility.m index ac52fb382..296b54595 100644 --- a/Source/Additions/GSCompatibility.m +++ b/Source/Additions/GSCompatibility.m @@ -19,7 +19,8 @@ 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., 51 Franklin Street, Fifth Floor, Boston, MA 02111 USA. + Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02111 USA. */ #include "config.h" @@ -27,16 +28,11 @@ #include "GNUstepBase/GSCategories.h" #include "GNUstepBase/GCObject.h" -NSString *GetEncodingName(NSStringEncoding availableEncodingValue) -{ - // Deprecated - return GSEncodingName(availableEncodingValue); -} - -NSString *GSEncodingName(NSStringEncoding availableEncodingValue) -{ - return (NSString *)CFStringGetNameOfEncoding(CFStringConvertNSStringEncodingToEncoding(availableEncodingValue)); -} +/* Avoid compiler warnings about internal method +*/ +@interface NSError (GNUstep) ++ (NSError*) _last; +@end NSThread *GSCurrentThread() { @@ -50,7 +46,7 @@ NSMutableDictionary *GSCurrentThreadDictionary() NSArray *NSStandardLibraryPaths() { - return NSSearchPathForDirectoriesInDomains(NSAllLibrariesDirectory, + return NSSearchPathForDirectoriesInDomains(NSAllLibrariesDirectory, NSAllDomainsMask, YES); } @@ -68,28 +64,28 @@ void NSDecimalFromComponents(NSDecimal *result, NSString* GSDebugMethodMsg(id obj, SEL sel, const char *file, int line, NSString *fmt) { - NSString *message; - Class cls = (Class)obj; - char c = '+'; + NSString *message; + Class cls = (Class)obj; + char c = '+'; - if ([obj isInstance] == YES) + if ([obj isInstance] == YES) { - c = '-'; - cls = [obj class]; + c = '-'; + cls = [obj class]; } - message = [NSString stringWithFormat: @"File %s: %d. In [%@ %c%@] %@", - file, line, NSStringFromClass(cls), c, NSStringFromSelector(sel), fmt]; - return message; + message = [NSString stringWithFormat: @"File %s: %d. In [%@ %c%@] %@", + file, line, NSStringFromClass(cls), c, NSStringFromSelector(sel), fmt]; + return message; } NSString* GSDebugFunctionMsg(const char *func, const char *file, int line, NSString *fmt) { - NSString *message; + NSString *message; - message = [NSString stringWithFormat: @"File %s: %d. In %s %@", - file, line, func, fmt]; - return message; + message = [NSString stringWithFormat: @"File %s: %d. In %s %@", + file, line, func, fmt]; + return message; } @implementation NSArray (GSCompatibility) @@ -260,7 +256,7 @@ getAddr(NSString* name, NSString* svc, NSString* pcl, struct sockaddr_in *sin) if ((net = socket(AF_INET, SOCK_STREAM, PF_UNSPEC)) < 0) { - NSLog(@"unable to create socket - %s", GSLastErrorStr(errno)); + NSLog(@"unable to create socket - %@", [NSError _last]); RELEASE(self); return nil; } @@ -277,8 +273,8 @@ getAddr(NSString* name, NSString* svc, NSString* pcl, struct sockaddr_in *sin) if (bind(net, (struct sockaddr *)&sin, sizeof(sin)) < 0) { - NSLog(@"unable to bind to port %s:%d - %s", inet_ntoa(sin.sin_addr), - NSSwapBigShortToHost(sin.sin_port), GSLastErrorStr(errno)); + NSLog(@"unable to bind to port %s:%d - %@", inet_ntoa(sin.sin_addr), + NSSwapBigShortToHost(sin.sin_port), [NSError _last]); (void) close(net); RELEASE(self); return nil; @@ -286,7 +282,7 @@ getAddr(NSString* name, NSString* svc, NSString* pcl, struct sockaddr_in *sin) if (listen(net, 5) < 0) { - NSLog(@"unable to listen on port - %s", GSLastErrorStr(errno)); + NSLog(@"unable to listen on port - %@", [NSError _last]); (void) close(net); RELEASE(self); return nil; @@ -294,7 +290,7 @@ getAddr(NSString* name, NSString* svc, NSString* pcl, struct sockaddr_in *sin) if (getsockname(net, (struct sockaddr*)&sin, &size) < 0) { - NSLog(@"unable to get socket name - %s", GSLastErrorStr(errno)); + NSLog(@"unable to get socket name - %@", [NSError _last]); (void) close(net); RELEASE(self); return nil; @@ -323,7 +319,7 @@ getAddr(NSString* name, NSString* svc, NSString* pcl, struct sockaddr_in *sin) if (getsockname([self fileDescriptor], (struct sockaddr*)&sin, &size) < 0) { - NSLog(@"unable to get socket name - %s", GSLastErrorStr(errno)); + NSLog(@"unable to get socket name - %@", [NSError _last]); return nil; } @@ -363,23 +359,23 @@ BOOL GSDebugSet(NSString *level) - (NSMutableSet *) debugSet // Derived from GNUStep's { - if (_debug_set == nil){ - int argc = [[self arguments] count]; - NSMutableSet *mySet; - int i; + if (_debug_set == nil) + { + int argc = [[self arguments] count]; + NSMutableSet *mySet; + int i; - mySet = [NSMutableSet new]; - for (i = 0; i < argc; i++) - { - NSString *str = [[self arguments] objectAtIndex:i]; + mySet = [NSMutableSet new]; + for (i = 0; i < argc; i++) + { + NSString *str = [[self arguments] objectAtIndex:i]; - if ([str hasPrefix: @"--GNU-Debug="]) - [mySet addObject: [str substringFromIndex: 12]]; - } - _debug_set = mySet; + if ([str hasPrefix: @"--GNU-Debug="]) + [mySet addObject: [str substringFromIndex: 12]]; + } + _debug_set = mySet; } - - return _debug_set; + return _debug_set; } @end @@ -394,15 +390,15 @@ BOOL GSDebugSet(NSString *level) */ - (BOOL) boolValue { - if ([self caseInsensitiveCompare: @"YES"] == NSOrderedSame) + if ([self caseInsensitiveCompare: @"YES"] == NSOrderedSame) { return YES; } - if ([self caseInsensitiveCompare: @"true"] == NSOrderedSame) + if ([self caseInsensitiveCompare: @"true"] == NSOrderedSame) { return YES; } - return [self intValue] != 0 ? YES : NO; + return [self intValue] != 0 ? YES : NO; } - (NSString*) substringFromRange:(NSRange)range @@ -416,13 +412,13 @@ BOOL GSDebugSet(NSString *level) - (retval_t) returnFrame:(arglist_t)args { #warning (stephane@sente.ch) Not implemented - return (retval_t)[self notImplemented:_cmd]; + return (retval_t)[self notImplemented:_cmd]; } - (id) initWithArgframe:(arglist_t)args selector:(SEL)selector { #warning (stephane@sente.ch) Not implemented - return [self notImplemented:_cmd]; + return [self notImplemented:_cmd]; } @end diff --git a/Source/Additions/GSFunctions.m b/Source/Additions/GSFunctions.m index 169ede7bd..9d9529a28 100644 --- a/Source/Additions/GSFunctions.m +++ b/Source/Additions/GSFunctions.m @@ -28,6 +28,7 @@ #include "config.h" #include "GNUstepBase/preface.h" #include "GNUstepBase/GSFunctions.h" +#include "GNUstepBase/GSCategories.h" #include "Foundation/Foundation.h" NSString * @@ -40,6 +41,8 @@ GSFindNamedFile(NSArray *paths, NSString *aName, NSString *anExtension) NSCParameterAssert(aName != nil); NSCParameterAssert(paths != nil); +GSOnceFLog(@"deprecated ... trivial to code directly"); + /* make up the name with extension if given */ if (anExtension != nil) { diff --git a/Source/Additions/GSMime.m b/Source/Additions/GSMime.m index 2b8998ed2..1e3642aa1 100644 --- a/Source/Additions/GSMime.m +++ b/Source/Additions/GSMime.m @@ -56,6 +56,7 @@ #include "GNUstepBase/GSMime.h" #include "GNUstepBase/GSXML.h" #include "GNUstepBase/GSCategories.h" +#include "GNUstepBase/Unicode.h" #include #include diff --git a/Source/Additions/GSObjCRuntime.m b/Source/Additions/GSObjCRuntime.m index 452274c9f..a1c13cc25 100644 --- a/Source/Additions/GSObjCRuntime.m +++ b/Source/Additions/GSObjCRuntime.m @@ -117,14 +117,6 @@ GSAllocateMutexAt(objc_mutex_t *request) objc_mutex_unlock(local_lock); } -/** Deprecated ... use GSObjCFindVariable() */ -BOOL -GSFindInstanceVariable(id obj, const char *name, - const char **type, unsigned int *size, int *offset) -{ - return GSObjCFindVariable(obj, name, type, size, offset); -} - /** * This function is used to locate information about the instance * variable of obj called name. It returns YES if the variable @@ -274,16 +266,10 @@ GSObjCVariableNames(id obj) return array; } -/** Deprecated ... use GSObjCGetVariable() */ -void -GSGetVariable(id obj, int offset, unsigned int size, void *data) -{ - GSObjCGetVariable(obj, offset, size, data); -} /** * Gets the value from an instance variable in obj
* This function performs no checking ... you should use it only where - * you are providing information from a call to GSFindVariable() + * you are providing information from a call to GSObjCFindVariable() * and you know that the data area provided is the correct size. */ void @@ -292,12 +278,6 @@ GSObjCGetVariable(id obj, int offset, unsigned int size, void *data) memcpy(data, ((void*)obj) + offset, size); } -/** Deprecated ... use GSObjCSetVariable() */ -void -GSSetVariable(id obj, int offset, unsigned int size, const void *data) -{ - GSObjCSetVariable(obj, offset, size, data); -} /** * Sets the value in an instance variable in obj
* This function performs no checking ... you should use it only where @@ -1475,13 +1455,6 @@ GSObjCAddClassBehavior(Class receiver, Class behavior) #endif -/** Deprecated ... use GSObjCGetVal() */ -id -GSGetValue(NSObject *self, NSString *key, SEL sel, - const char *type, unsigned size, int offset) -{ - return GSObjCGetVal(self, [key UTF8String], sel, type, size, offset); -} /** * This is used internally by the key-value coding methods, to get a * value from an object either via an accessor method (if sel is @@ -1801,13 +1774,6 @@ GSObjCGetValue(NSObject *self, NSString *key, SEL sel, return GSObjCGetVal(self, [key UTF8String], sel, type, size, offset); } -/** Deprecated ... use GSObjCSetVal() */ -void -GSSetValue(NSObject *self, NSString *key, id val, SEL sel, - const char *type, unsigned size, int offset) -{ - GSObjCSetVal(self, [key UTF8String], val, sel, type, size, offset); -} /** * This is used internally by the key-value coding methods, to set a * value in an object either via an accessor method (if sel is diff --git a/Source/Additions/GSXML.m b/Source/Additions/GSXML.m index 539af032f..010225a48 100644 --- a/Source/Additions/GSXML.m +++ b/Source/Additions/GSXML.m @@ -43,6 +43,7 @@ #include "config.h" #include "GNUstepBase/preface.h" #include "GNUstepBase/GSCategories.h" +#include "GNUstepBase/Unicode.h" #ifdef HAVE_LIBXML @@ -4934,6 +4935,7 @@ static void indentation(unsigned level, NSMutableString *str) NL; INDENT(3); [str appendString: @""]; + NL; INDENT(2); [str appendString: @""]; NL; @@ -5075,7 +5077,6 @@ static void indentation(unsigned level, NSMutableString *str) [handle writeProperty: pKey forKey: GSHTTPPropertyKeyFileKey]; [handle writeProperty: pwd forKey: GSHTTPPropertyPasswordKey]; } - [handle addClient: self]; #else connectionURL = [url copy]; connection = nil; @@ -5309,6 +5310,7 @@ static void indentation(unsigned level, NSMutableString *str) repeats: NO]; #ifdef GNUSTEP + [handle addClient: self]; [handle writeProperty: @"POST" forKey: GSHTTPPropertyMethodKey]; [handle writeProperty: @"GSXMLRPC/1.0.0" forKey: @"User-Agent"]; [handle writeProperty: @"text/xml" forKey: @"Content-Type"]; @@ -5393,6 +5395,9 @@ static void indentation(unsigned level, NSMutableString *str) ASSIGN(result, reason); [timer invalidate]; timer = nil; +#ifdef GNUSTEP + [handle removeClient: self]; +#endif if ([delegate respondsToSelector: @selector(completedXMLRPC:)]) { [delegate completedXMLRPC: self]; @@ -5406,9 +5411,23 @@ static void indentation(unsigned level, NSMutableString *str) - (void) URLHandleResourceDidCancelLoading: (NSURLHandle*)sender { - ASSIGN(result, @"timeout"); + NSString *str; + [timer invalidate]; timer = nil; +#ifdef GNUSTEP + [handle removeClient: self]; +#endif + str = [handle propertyForKeyIfAvailable: NSHTTPPropertyStatusCodeKey]; + if (str == nil) + { + str = @"timeout"; + } + else + { + str = [NSString stringWithFormat: @"HTTP status %@", str]; + } + ASSIGN(result, str); if ([delegate respondsToSelector: @selector(completedXMLRPC:)]) { [delegate completedXMLRPC: self]; @@ -5452,6 +5471,9 @@ static void indentation(unsigned level, NSMutableString *str) [timer invalidate]; timer = nil; +#ifdef GNUSTEP + [handle removeClient: self]; +#endif if ([delegate respondsToSelector: @selector(completedXMLRPC:)]) { @@ -5512,7 +5534,6 @@ didReceiveAuthenticationChallenge: (NSURLAuthenticationChallenge*)challenge { NSMutableArray *params = [NSMutableArray array]; id fault = nil; - int code; NS_DURING { diff --git a/Source/Additions/Makefile.preamble b/Source/Additions/Makefile.preamble index 8963da2f9..b68b1b068 100644 --- a/Source/Additions/Makefile.preamble +++ b/Source/Additions/Makefile.preamble @@ -55,8 +55,9 @@ endif ADDITIONAL_CFLAGS = # Additional include directories the compiler should search +# FIXME - the -I../ is for GSPrivate.h ADDITIONAL_INCLUDE_DIRS = -I../../Headers/Additions \ - -I../$(GNUSTEP_TARGET_DIR) + -I../$(GNUSTEP_TARGET_DIR) -I../ ifeq ($(FOUNDATION_LIB),gnu) ADDITIONAL_INCLUDE_DIRS += -I../../Headers diff --git a/Source/Additions/Unicode.m b/Source/Additions/Unicode.m index 8ca2f9190..6b95d9d51 100644 --- a/Source/Additions/Unicode.m +++ b/Source/Additions/Unicode.m @@ -24,7 +24,8 @@ 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., 51 Franklin Street, Fifth Floor, Boston, MA 02111 USA. + Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02111 USA. */ #include "config.h" @@ -32,6 +33,7 @@ #include #include #include +#include #include #include #include @@ -39,9 +41,13 @@ #else #include #endif + #include "GNUstepBase/GSLock.h" +#include "GNUstepBase/GSMime.h" #include "GNUstepBase/GSCategories.h" #include "GNUstepBase/Unicode.h" + +#include "../GSPrivate.h" #include #include #include @@ -52,15 +58,15 @@ typedef struct {unichar from; unsigned char to;} _ucc_; -#include "GNUstepBase/unicode/cyrillic.h" -#include "GNUstepBase/unicode/latin2.h" -#include "GNUstepBase/unicode/latin9.h" -#include "GNUstepBase/unicode/nextstep.h" -#include "GNUstepBase/unicode/caseconv.h" -#include "GNUstepBase/unicode/cop.h" -#include "GNUstepBase/unicode/decomp.h" -#include "GNUstepBase/unicode/gsm0338.h" -#include "GNUstepBase/unicode/thai.h" +#include "unicode/cyrillic.h" +#include "unicode/latin2.h" +#include "unicode/latin9.h" +#include "unicode/nextstep.h" +#include "unicode/caseconv.h" +#include "unicode/cop.h" +#include "unicode/decomp.h" +#include "unicode/gsm0338.h" +#include "unicode/thai.h" #ifdef HAVE_ICONV #ifdef HAVE_GICONV_H @@ -130,6 +136,7 @@ static GSLazyLock *local_lock = nil; typedef unsigned char unc; static NSStringEncoding defEnc = GSUndefinedEncoding; +static NSStringEncoding natEnc = GSUndefinedEncoding; static NSStringEncoding *_availableEncodings = 0; struct _strenc_ { @@ -329,7 +336,8 @@ static void GSSetupEncodingTable(void) } } -BOOL GSEncodingSupported(NSStringEncoding enc) +BOOL +GSPrivateIsEncodingSupported(NSStringEncoding enc) { GSSetupEncodingTable(); @@ -385,46 +393,6 @@ BOOL GSEncodingSupported(NSStringEncoding enc) return NO; } -/** - * Returns a nul terminated array of the available string encodings. - */ -NSStringEncoding * -GetAvailableEncodings() -{ - if (_availableEncodings == 0) - { - GSSetupEncodingTable(); - [GS_INITIALIZED_LOCK(local_lock, GSLazyLock) lock]; - if (_availableEncodings == 0) - { - NSStringEncoding *encodings; - unsigned pos; - unsigned i; - - /* - * Now build up a list of supported encodings ... in the - * format needed to support [NSString+availableStringEncodings] - * Check to see what iconv support we have as we go along. - * This is also the place where we determine the name we use - * for iconv to support unicode. - */ - encodings = objc_malloc(sizeof(NSStringEncoding) * (encTableSize+1)); - pos = 0; - for (i = 0; i < encTableSize+1; i++) - { - if (GSEncodingSupported(i) == YES) - { - encodings[pos++] = i; - } - } - encodings[pos] = 0; - _availableEncodings = encodings; - } - [local_lock unlock]; - } - return _availableEncodings; -} - /** Returns the NSStringEncoding that matches the specified * character set registry and encoding information. For instance, * for the iso8859-5 character set, the registry is iso8859 and @@ -435,95 +403,13 @@ GetAvailableEncodings() NSStringEncoding GSEncodingForRegistry (NSString *registry, NSString *encoding) { - if ([registry isEqualToString: @"iso8859"]) - { - if ([encoding isEqualToString: @"1"]) - return NSISOLatin1StringEncoding; - else if ([encoding isEqualToString: @"2"]) - return NSISOLatin2StringEncoding; - else if ([encoding isEqualToString: @"3"]) - return NSISOLatin3StringEncoding; - else if ([encoding isEqualToString: @"4"]) - return NSISOLatin4StringEncoding; - else if ([encoding isEqualToString: @"5"]) - return NSISOCyrillicStringEncoding; - else if ([encoding isEqualToString: @"6"]) - return NSISOArabicStringEncoding; - else if ([encoding isEqualToString: @"7"]) - return NSISOGreekStringEncoding; - else if ([encoding isEqualToString: @"8"]) - return NSISOHebrewStringEncoding; - else if ([encoding isEqualToString: @"11"]) - return NSISOThaiStringEncoding; - else if ([encoding isEqualToString: @"15"]) - return NSISOLatin9StringEncoding; - // Other latin encodings are currently not supported - } - else if ([registry isEqualToString: @"iso10646"]) - { - if ([encoding isEqualToString: @"1"]) - return NSUnicodeStringEncoding; - } - else if ([registry isEqualToString: @"microsoft"]) - { - if ([encoding isEqualToString: @"symbol"]) - return NSSymbolStringEncoding; - else if ([encoding isEqualToString: @"cp1250"]) - return NSWindowsCP1250StringEncoding; - else if ([encoding isEqualToString: @"cp1251"]) - return NSWindowsCP1251StringEncoding; - else if ([encoding isEqualToString: @"cp1252"]) - return NSWindowsCP1252StringEncoding; - else if ([encoding isEqualToString: @"cp1253"]) - return NSWindowsCP1253StringEncoding; - else if ([encoding isEqualToString: @"cp1254"]) - return NSWindowsCP1254StringEncoding; - } - else if ([registry isEqualToString: @"apple"]) - { - if ([encoding isEqualToString: @"roman"]) - return NSMacOSRomanStringEncoding; - } - else if ([registry isEqualToString: @"jisx0201.1976"]) - { - if ([encoding isEqualToString: @"0"]) - return NSShiftJISStringEncoding; - } - else if ([registry isEqualToString: @"iso646.1991"]) - { - if ([encoding isEqualToString: @"irv"]) - return NSASCIIStringEncoding; - } - else if ([registry isEqualToString: @"koi8"]) - { - if ([encoding isEqualToString: @"r"]) - return NSKOI8RStringEncoding; - } - else if ([registry isEqualToString: @"gb2312.1980"]) - { - if ([encoding isEqualToString: @"0"]) - return NSGB2312StringEncoding; - } - else if ([registry isEqualToString: @"big5"]) - { - if ([encoding isEqualToString: @"0"]) - return NSBIG5StringEncoding; - } - else if ([registry isEqualToString: @"ksc5601.1987"]) - { - return NSKoreanEUCStringEncoding; - } - else if ([registry isEqualToString: @"ksc5601.1997"]) - { - return NSKoreanEUCStringEncoding; - } - else if ([registry isEqualToString:@"utf8"] - || [registry isEqualToString:@"utf-8"]) - { - return NSUTF8StringEncoding; - } + NSString *charset = registry; - return GSUndefinedEncoding; + if ([encoding length] > 0 && [encoding isEqualToString: @"0"] == NO) + { + charset = [NSString stringWithFormat: @"%@-%@", registry, encoding]; + } + return [GSMimeDocument encodingFromCharset: charset]; } /** Try to deduce the string encoding from the locale string @@ -532,7 +418,7 @@ GSEncodingForRegistry (NSString *registry, NSString *encoding) * deduced from the clocale string itself. If clocale isn't set or * no match can be found, returns GSUndefinedEncoding. */ -/* It would be really nice if this could be used in GetDefEncoding, but +/* It would be really nice if this could be used in +defaultCStringEncoding, but * there are too many dependancies on other parts of the library to * make this practical (even if everything possible was written in C, * we'd still need some way to find the Locale.encodings file). @@ -555,23 +441,25 @@ GSEncodingFromLocale(const char *clocale) /* Locale contains the 'codeset' section. Parse it and see if we know what encoding this cooresponds to */ NSString *registry; + NSString *charset; NSArray *array; char *s; s = strchr (clocale, '.'); - registry = [[NSString stringWithCString: s+1] lowercaseString]; + registry = [[NSString stringWithUTF8String: s+1] lowercaseString]; array = [registry componentsSeparatedByString: @"-"]; registry = [array objectAtIndex: 0]; if ([array count] > 1) { - encodstr = [array lastObject]; + charset = [NSString stringWithFormat: @"%@-%@", + registry, [array lastObject]]; } else { - encodstr = @"0"; + charset = registry; } - encoding = GSEncodingForRegistry(registry, encodstr); + encoding = [GSMimeDocument encodingFromCharset: charset]; } else { @@ -594,7 +482,7 @@ GSEncodingFromLocale(const char *clocale) dict = [NSDictionary dictionaryWithContentsOfFile: table]; encodstr = [dict objectForKey: - [NSString stringWithCString: clocale]]; + [NSString stringWithUTF8String: clocale]]; if (encodstr == nil) return GSUndefinedEncoding; @@ -620,299 +508,6 @@ GSEncodingFromLocale(const char *clocale) return encoding; } -/** - * Return the default encoding - */ -NSStringEncoding -GetDefEncoding(void) -{ - if (defEnc == GSUndefinedEncoding) - { - char *encoding; - unsigned int count; - - GSSetupEncodingTable(); - - [GS_INITIALIZED_LOCK(local_lock, GSLazyLock) lock]; - if (defEnc != GSUndefinedEncoding) - { - [local_lock unlock]; - return defEnc; - } - - encoding = getenv("GNUSTEP_STRING_ENCODING"); - if (encoding != 0) - { - count = 0; - while (str_encoding_table[count].enc - && strcasecmp(str_encoding_table[count].ename, encoding) - && strcasecmp(str_encoding_table[count].iconv, encoding)) - { - count++; - } - if (str_encoding_table[count].enc) - { - defEnc = str_encoding_table[count].enc; - } - else - { - fprintf(stderr, - "WARNING: %s - encoding not supported.\n", encoding); - fprintf(stderr, - " NSISOLatin1StringEncoding set as default.\n"); - defEnc = NSISOLatin1StringEncoding; - } - } - if (defEnc == GSUndefinedEncoding) - { - /* Encoding not set */ -#if HAVE_LANGINFO_CODESET - /* Take it from the system locale information. */ - encoding = nl_langinfo(CODESET); -/* - * First handle the fallback response from nl_langinfo() ... - * if we are getting the default value we can't assume that - * the user has set anything up at all, so we must use the - * OpenStep/GNUstep default encopding ... latin1, even though - * the nl_langinfo() stuff would say default is ascii. - */ - if (strcmp(encoding, "ANSI_X3.4-1968") == 0 /* glibc */ - || strcmp(encoding, "ISO_646.IRV:1983") == 0 /* glibc */ - || strcmp(encoding, "646") == 0 /* Solaris NetBSD */) - defEnc = NSISOLatin1StringEncoding; - else if (strcmp(encoding, "EUC-JP") == 0 /* glibc */ - /* HP-UX IRIX OSF/1 Solaris NetBSD */ - || strcmp(encoding, "eucJP") == 0 - || strcmp(encoding, "IBM-eucJP") == 0 /* AIX */) - defEnc = NSJapaneseEUCStringEncoding; - else if (strcmp(encoding, "UTF-8") == 0 /* glibc AIX OSF/1 Solaris */ - || strcmp(encoding, "utf8") == 0 /* HP-UX */) - defEnc = NSUTF8StringEncoding; - else if (strcmp(encoding, "ISO-8859-1") == 0 /* glibc */ - /* AIX IRIX OSF/1 Solaris NetBSD */ - || strcmp(encoding, "ISO8859-1") == 0 - || strcmp(encoding, "iso88591") == 0 /* HP-UX */) - defEnc = NSISOLatin1StringEncoding; - else if (strcmp(encoding, "IBM-932") == 0 /* AIX */ - || strcmp(encoding, "SJIS") == 0 /* HP-UX OSF/1 NetBSD */ - || strcmp(encoding, "PCK") == 0 /* Solaris */) - defEnc = NSShiftJISStringEncoding; - else if (strcmp(encoding, "ISO-8859-2") == 0 /* glibc */ - /* AIX IRIX OSF/1 Solaris NetBSD */ - || strcmp(encoding, "ISO8859-2") == 0 - || strcmp(encoding, "iso88592") == 0 /* HP-UX */) - defEnc = NSISOLatin2StringEncoding; - else if (strcmp(encoding, "CP1251") == 0 /* glibc */ - || strcmp(encoding, "ansi-1251") == 0 /* Solaris */) - defEnc = NSWindowsCP1251StringEncoding; - else if (strcmp(encoding, "CP1252") == 0 /* */ - || strcmp(encoding, "IBM-1252") == 0 /* AIX */) - defEnc = NSWindowsCP1252StringEncoding; - else if (strcmp(encoding, "ISO-8859-5") == 0 /* glibc */ - /* AIX IRIX OSF/1 Solaris NetBSD */ - || strcmp(encoding, "ISO8859-5") == 0 - || strcmp(encoding, "iso88595") == 0 /* HP-UX */) - defEnc = NSISOCyrillicStringEncoding; - else if (strcmp(encoding, "KOI8-R") == 0 /* glibc */ - || strcmp(encoding, "koi8-r") == 0 /* Solaris */) - defEnc = NSKOI8RStringEncoding; - else if (strcmp(encoding, "ISO-8859-3") == 0 /* glibc */ - || strcmp(encoding, "ISO8859-3") == 0 /* Solaris */) - defEnc = NSISOLatin3StringEncoding; - else if (strcmp(encoding, "ISO-8859-4") == 0 /* */ - || strcmp(encoding, "ISO8859-4") == 0 /* OSF/1 Solaris NetBSD */) - defEnc = NSISOLatin4StringEncoding; - else if (strcmp(encoding, "ISO-8859-6") == 0 /* glibc */ - || strcmp(encoding, "ISO8859-6") == 0 /* AIX Solaris */ - || strcmp(encoding, "iso88596") == 0 /* HP-UX */) - defEnc = NSISOArabicStringEncoding; - else if (strcmp(encoding, "ISO-8859-7") == 0 /* glibc */ - || strcmp(encoding, "ISO8859-7") == 0 /* AIX IRIX OSF/1 Solaris */ - || strcmp(encoding, "iso88597") == 0 /* HP-UX */) - defEnc = NSISOGreekStringEncoding; - else if (strcmp(encoding, "ISO-8859-8") == 0 /* glibc */ - || strcmp(encoding, "ISO8859-8") == 0 /* AIX OSF/1 Solaris */ - || strcmp(encoding, "iso88598") == 0 /* HP-UX */) - defEnc = NSISOHebrewStringEncoding; - else if (strcmp(encoding, "ISO-8859-9") == 0 /* glibc */ - || strcmp(encoding, "ISO8859-9") == 0 /* AIX IRIX OSF/1 Solaris */ - || strcmp(encoding, "iso88599") == 0 /* HP-UX */) - defEnc = NSISOLatin5StringEncoding; - else if (strcmp(encoding, "ISO-8859-10") == 0 /* */ - || strcmp(encoding, "ISO8859-10") == 0 /* */) - defEnc = NSISOLatin6StringEncoding; - else if (strcmp(encoding, "TIS-620") == 0 /* glibc AIX */ - || strcmp(encoding, "tis620") == 0 /* HP-UX */ - || strcmp(encoding, "TIS620.2533") == 0 /* Solaris */ - || strcmp(encoding, "TACTIS") == 0 /* OSF/1 */) - defEnc = NSISOThaiStringEncoding; - else if (strcmp(encoding, "ISO-8859-13") == 0 /* glibc */ - || strcmp(encoding, "ISO8859-13") == 0 /* */ - || strcmp(encoding, "IBM-921") == 0 /* AIX */) - defEnc = NSISOLatin7StringEncoding; - else if (strcmp(encoding, "ISO-8859-14") == 0 /* glibc */ - || strcmp(encoding, "ISO8859-14") == 0 /* */) - defEnc = NSISOLatin8StringEncoding; - else if (strcmp(encoding, "ISO-8859-15") == 0 /* glibc */ - /* AIX OSF/1 Solaris NetBSD */ - || strcmp(encoding, "ISO8859-15") == 0 - || strcmp(encoding, "iso885915") == 0 /* HP-UX */) - defEnc = NSISOLatin9StringEncoding; - else if (strcmp(encoding, "GB2312") == 0 /* glibc */ - || strcmp(encoding, "gb2312") == 0 /* Solaris */ - || strcmp(encoding, "eucCN") == 0 /* IRIX NetBSD */ - || strcmp(encoding, "IBM-eucCN") == 0 /* AIX */ - || strcmp(encoding, "hp15CN") == 0 /* HP-UX */) - defEnc = NSGB2312StringEncoding; - else if (strcmp(encoding, "BIG5") == 0 /* glibc Solaris NetBSD */ - || strcmp(encoding, "big5") == 0 /* AIX HP-UX OSF/1 */) - defEnc = NSBIG5StringEncoding; - else if (strcmp(encoding, "EUC-KR") == 0 /* glibc */ - || strcmp(encoding, "eucKR") == 0 /* HP-UX IRIX OSF/1 NetBSD */ - || strcmp(encoding, "IBM-eucKR") == 0 /* AIX */ - || strcmp(encoding, "5601") == 0 /* Solaris */) - defEnc = NSKoreanEUCStringEncoding; - else -#endif - defEnc = NSISOLatin1StringEncoding; - } - else if (GSEncodingSupported(defEnc) == NO) - { - fprintf(stderr, "WARNING: %s - encoding not implemented as " - "default c string encoding.\n", encoding); - fprintf(stderr, - " NSISOLatin1StringEncoding set as default.\n"); - defEnc = NSISOLatin1StringEncoding; - } - [local_lock unlock]; - } - return defEnc; -} - -BOOL -GSIsByteEncoding(NSStringEncoding encoding) -{ - if (GSEncodingSupported(encoding) == NO) - { - return NO; - } - return encodingTable[encoding]->eightBit; -} - -/** - * Returns the standard name for the specified encoding. - */ -#ifndef NeXT_Foundation_LIBRARY -NSString* -GSEncodingName(NSStringEncoding encoding) -{ - if (GSEncodingSupported(encoding) == NO) - { - return @"Unknown encoding"; - } - return [NSString stringWithCString: encodingTable[encoding]->ename]; -} -#endif - -/** - * deprecated Use GSEncodingName() - */ -#ifndef NeXT_Foundation_LIBRARY -NSString* -GetEncodingName(NSStringEncoding encoding) -{ - return GSEncodingName(encoding); -} -#endif - -/** - * deprecated - * See GSToUnicode() and GSFromUnicode() - */ -unichar -encode_chartouni(unsigned char c, NSStringEncoding enc) -{ - BOOL result; - unsigned int size = 1; - unichar u = 0; - unichar *dst = &u; - - result = GSToUnicode(&dst, &size, &c, 1, enc, 0, 0); - if (result == NO) - { - return 0; - } - return u; -} - -/** - * deprecated - * See GSToUnicode() and GSFromUnicode() - */ -unsigned char -encode_unitochar(unichar u, NSStringEncoding enc) -{ - BOOL result; - unsigned int size = 1; - unsigned char c = 0; - unsigned char *dst = &c; - - result = GSFromUnicode(&dst, &size, &u, 1, enc, 0, 0); - if (result == NO) - { - return 0; - } - return c; -} - -/** - * deprecated - * See GSToUnicode() and GSFromUnicode() - */ -unsigned -encode_unitochar_strict(unichar u, NSStringEncoding enc) -{ - BOOL result; - unsigned int size = 1; - unsigned char c = 0; - unsigned char *dst = &c; - - result = GSFromUnicode(&dst, &size, &u, 1, enc, 0, GSUniStrict); - if (result == NO) - { - return 0; - } - return c; -} - -/** - * deprecated - * See GSToUnicode() and GSFromUnicode() - */ -unichar -chartouni(unsigned char c) -{ - if (defEnc == GSUndefinedEncoding) - { - defEnc = GetDefEncoding(); - } - return encode_chartouni(c, defEnc); -} - -/** - * deprecated - * See GSToUnicode() and GSFromUnicode() - */ -unsigned char -unitochar(unichar u) -{ - if (defEnc == GSUndefinedEncoding) - { - defEnc = GetDefEncoding(); - } - return encode_unitochar(u, defEnc); -} - /** * Uses direct access into a two-level table to map cases.
* The two-level table method is less space efficient (but still not bad) than @@ -942,7 +537,7 @@ uni_toupper(unichar ch) } unsigned char -uni_cop(unichar u) +GSPrivateUniCop(unichar u) { if (u < uni_cop_table[0].code) { @@ -987,6 +582,12 @@ uni_cop(unichar u) } } +unsigned char +uni_cop(unichar u) +{ + return GSPrivateUniCop(u); +} + BOOL uni_isnonsp(unichar u) { @@ -998,7 +599,7 @@ uni_isnonsp(unichar u) return YES; // FIXME check is uni_cop good for this - if (uni_cop(u)) + if (GSPrivateUniCop(u)) return YES; else return NO; @@ -1050,46 +651,6 @@ uni_is_decomp(unichar u) } } -/** - * deprecated - * See GSToUnicode() and GSFromUnicode() - */ -int encode_ustrtocstr(char *dst, int dl, const unichar *src, int sl, - NSStringEncoding enc, BOOL strict) -{ - BOOL result; - unsigned int options = (strict == YES) ? GSUniStrict : 0; - unsigned int old = dl; - - result = GSFromUnicode((unsigned char**)&dst, (unsigned int*)&dl, - src, sl, enc, 0, options); - if (result == NO) - { - return 0; - } - return old - dl; // Number of characters. -} - -/** - * deprecated - * See GSToUnicode() and GSFromUnicode() - */ -int encode_cstrtoustr(unichar *dst, int dl, const char *src, int sl, - NSStringEncoding enc) -{ - BOOL result; - unsigned int old = dl; - - result = GSToUnicode(&dst, (unsigned int*)&dl, (unsigned char*)src, - sl, enc, 0, 0); - if (result == NO) - { - return 0; - } - return old - dl; -} - - /** * Function to check a block of data for validity as a unicode string and * say whether it contains solely ASCII or solely Latin1 data.
@@ -1531,7 +1092,7 @@ tables: const char *estr = 0; BOOL done = NO; - if (GSEncodingSupported(enc) == YES) + if (GSPrivateIsEncodingSupported(enc) == YES) { estr = encodingTable[enc]->iconv; } @@ -1552,7 +1113,7 @@ tables: if (cd == (iconv_t)-1) { NSLog(@"No iconv for encoding %@ tried to use %s", - GetEncodingName(enc), estr); + GSPrivateEncodingName(enc), estr); result = NO; goto done; } @@ -2224,7 +1785,7 @@ iconv_start: const char *estr = 0; BOOL done = NO; - if (GSEncodingSupported(enc) == YES) + if (GSPrivateIsEncodingSupported(enc) == YES) { if (strict == NO) { @@ -2257,7 +1818,7 @@ iconv_start: if (cd == (iconv_t)-1) { NSLog(@"No iconv for encoding %@ tried to use %s", - GetEncodingName(enc), estr); + GSPrivateEncodingName(enc), estr); result = NO; goto done; } @@ -2414,3 +1975,253 @@ iconv_start: #undef GROW + + +NSStringEncoding* +GSPrivateAvailableEncodings() +{ + if (_availableEncodings == 0) + { + GSSetupEncodingTable(); + [GS_INITIALIZED_LOCK(local_lock, GSLazyLock) lock]; + if (_availableEncodings == 0) + { + NSStringEncoding *encodings; + unsigned pos; + unsigned i; + + /* + * Now build up a list of supported encodings ... in the + * format needed to support [NSString+availableStringEncodings] + * Check to see what iconv support we have as we go along. + * This is also the place where we determine the name we use + * for iconv to support unicode. + */ + encodings = objc_malloc(sizeof(NSStringEncoding) * (encTableSize+1)); + pos = 0; + for (i = 0; i < encTableSize+1; i++) + { + if (GSPrivateIsEncodingSupported(i) == YES) + { + encodings[pos++] = i; + } + } + encodings[pos] = 0; + _availableEncodings = encodings; + } + [local_lock unlock]; + } + return _availableEncodings; +} + +NSStringEncoding +GSPrivateDefaultCStringEncoding() +{ + if (defEnc == GSUndefinedEncoding) + { + char *encoding; + unsigned int count; + + GSSetupEncodingTable(); + + [GS_INITIALIZED_LOCK(local_lock, GSLazyLock) lock]; + if (defEnc != GSUndefinedEncoding) + { + [local_lock unlock]; + return defEnc; + } + + if (natEnc == GSUndefinedEncoding) + { + /* Encoding not set */ +#if HAVE_LANGINFO_CODESET + /* Take it from the system locale information. */ + encoding = nl_langinfo(CODESET); + /* + * First handle the fallback response from nl_langinfo() ... + * if we are getting the default value we can't assume that + * the user has set anything up at all, so we must use the + * OpenStep/GNUstep default encopding ... latin1, even though + * the nl_langinfo() stuff would say default is ascii. + */ + if (strcmp(encoding, "ANSI_X3.4-1968") == 0 /* glibc */ + || strcmp(encoding, "ISO_646.IRV:1983") == 0 /* glibc */ + || strcmp(encoding, "646") == 0 /* Solaris NetBSD */) + natEnc = NSISOLatin1StringEncoding; + else if (strcmp(encoding, "EUC-JP") == 0 /* glibc */ + /* HP-UX IRIX OSF/1 Solaris NetBSD */ + || strcmp(encoding, "eucJP") == 0 + || strcmp(encoding, "IBM-eucJP") == 0 /* AIX */) + natEnc = NSJapaneseEUCStringEncoding; + else if (strcmp(encoding, "UTF-8") == 0 /* glibc AIX OSF/1 Solaris */ + || strcmp(encoding, "utf8") == 0 /* HP-UX */) + natEnc = NSUTF8StringEncoding; + else if (strcmp(encoding, "ISO-8859-1") == 0 /* glibc */ + /* AIX IRIX OSF/1 Solaris NetBSD */ + || strcmp(encoding, "ISO8859-1") == 0 + || strcmp(encoding, "iso88591") == 0 /* HP-UX */) + natEnc = NSISOLatin1StringEncoding; + else if (strcmp(encoding, "IBM-932") == 0 /* AIX */ + || strcmp(encoding, "SJIS") == 0 /* HP-UX OSF/1 NetBSD */ + || strcmp(encoding, "PCK") == 0 /* Solaris */) + natEnc = NSShiftJISStringEncoding; + else if (strcmp(encoding, "ISO-8859-2") == 0 /* glibc */ + /* AIX IRIX OSF/1 Solaris NetBSD */ + || strcmp(encoding, "ISO8859-2") == 0 + || strcmp(encoding, "iso88592") == 0 /* HP-UX */) + natEnc = NSISOLatin2StringEncoding; + else if (strcmp(encoding, "CP1251") == 0 /* glibc */ + || strcmp(encoding, "ansi-1251") == 0 /* Solaris */) + natEnc = NSWindowsCP1251StringEncoding; + else if (strcmp(encoding, "CP1252") == 0 /* */ + || strcmp(encoding, "IBM-1252") == 0 /* AIX */) + natEnc = NSWindowsCP1252StringEncoding; + else if (strcmp(encoding, "ISO-8859-5") == 0 /* glibc */ + /* AIX IRIX OSF/1 Solaris NetBSD */ + || strcmp(encoding, "ISO8859-5") == 0 + || strcmp(encoding, "iso88595") == 0 /* HP-UX */) + natEnc = NSISOCyrillicStringEncoding; + else if (strcmp(encoding, "KOI8-R") == 0 /* glibc */ + || strcmp(encoding, "koi8-r") == 0 /* Solaris */) + natEnc = NSKOI8RStringEncoding; + else if (strcmp(encoding, "ISO-8859-3") == 0 /* glibc */ + || strcmp(encoding, "ISO8859-3") == 0 /* Solaris */) + natEnc = NSISOLatin3StringEncoding; + else if (strcmp(encoding, "ISO-8859-4") == 0 /* */ + || strcmp(encoding, "ISO8859-4") == 0 /* OSF/1 Solaris NetBSD */) + natEnc = NSISOLatin4StringEncoding; + else if (strcmp(encoding, "ISO-8859-6") == 0 /* glibc */ + || strcmp(encoding, "ISO8859-6") == 0 /* AIX Solaris */ + || strcmp(encoding, "iso88596") == 0 /* HP-UX */) + natEnc = NSISOArabicStringEncoding; + else if (strcmp(encoding, "ISO-8859-7") == 0 /* glibc */ + || strcmp(encoding, "ISO8859-7") == 0 /* AIX IRIX OSF/1 Solaris */ + || strcmp(encoding, "iso88597") == 0 /* HP-UX */) + natEnc = NSISOGreekStringEncoding; + else if (strcmp(encoding, "ISO-8859-8") == 0 /* glibc */ + || strcmp(encoding, "ISO8859-8") == 0 /* AIX OSF/1 Solaris */ + || strcmp(encoding, "iso88598") == 0 /* HP-UX */) + natEnc = NSISOHebrewStringEncoding; + else if (strcmp(encoding, "ISO-8859-9") == 0 /* glibc */ + || strcmp(encoding, "ISO8859-9") == 0 /* AIX IRIX OSF/1 Solaris */ + || strcmp(encoding, "iso88599") == 0 /* HP-UX */) + natEnc = NSISOLatin5StringEncoding; + else if (strcmp(encoding, "ISO-8859-10") == 0 /* */ + || strcmp(encoding, "ISO8859-10") == 0 /* */) + natEnc = NSISOLatin6StringEncoding; + else if (strcmp(encoding, "TIS-620") == 0 /* glibc AIX */ + || strcmp(encoding, "tis620") == 0 /* HP-UX */ + || strcmp(encoding, "TIS620.2533") == 0 /* Solaris */ + || strcmp(encoding, "TACTIS") == 0 /* OSF/1 */) + natEnc = NSISOThaiStringEncoding; + else if (strcmp(encoding, "ISO-8859-13") == 0 /* glibc */ + || strcmp(encoding, "ISO8859-13") == 0 /* */ + || strcmp(encoding, "IBM-921") == 0 /* AIX */) + natEnc = NSISOLatin7StringEncoding; + else if (strcmp(encoding, "ISO-8859-14") == 0 /* glibc */ + || strcmp(encoding, "ISO8859-14") == 0 /* */) + natEnc = NSISOLatin8StringEncoding; + else if (strcmp(encoding, "ISO-8859-15") == 0 /* glibc */ + /* AIX OSF/1 Solaris NetBSD */ + || strcmp(encoding, "ISO8859-15") == 0 + || strcmp(encoding, "iso885915") == 0 /* HP-UX */) + natEnc = NSISOLatin9StringEncoding; + else if (strcmp(encoding, "GB2312") == 0 /* glibc */ + || strcmp(encoding, "gb2312") == 0 /* Solaris */ + || strcmp(encoding, "eucCN") == 0 /* IRIX NetBSD */ + || strcmp(encoding, "IBM-eucCN") == 0 /* AIX */ + || strcmp(encoding, "hp15CN") == 0 /* HP-UX */) + natEnc = NSGB2312StringEncoding; + else if (strcmp(encoding, "BIG5") == 0 /* glibc Solaris NetBSD */ + || strcmp(encoding, "big5") == 0 /* AIX HP-UX OSF/1 */) + natEnc = NSBIG5StringEncoding; + else if (strcmp(encoding, "EUC-KR") == 0 /* glibc */ + || strcmp(encoding, "eucKR") == 0 /* HP-UX IRIX OSF/1 NetBSD */ + || strcmp(encoding, "IBM-eucKR") == 0 /* AIX */ + || strcmp(encoding, "5601") == 0 /* Solaris */) + natEnc = NSKoreanEUCStringEncoding; +#endif + } + + encoding = getenv("GNUSTEP_STRING_ENCODING"); + if (encoding != 0) + { + count = 0; + while (str_encoding_table[count].enc + && strcasecmp(str_encoding_table[count].ename, encoding) + && strcasecmp(str_encoding_table[count].iconv, encoding)) + { + count++; + } + if (str_encoding_table[count].enc) + { + defEnc = str_encoding_table[count].enc; + } + else + { + fprintf(stderr, + "WARNING: %s - encoding not supported.\n", encoding); + fprintf(stderr, + " NSISOLatin1StringEncoding set as default.\n"); + defEnc = NSISOLatin1StringEncoding; + } + } + if (defEnc == GSUndefinedEncoding) + { + defEnc = natEnc; + } + if (defEnc == GSUndefinedEncoding) + { + defEnc = NSISOLatin1StringEncoding; + } + else if (GSPrivateIsEncodingSupported(defEnc) == NO) + { + fprintf(stderr, "WARNING: %s - encoding not implemented as " + "default c string encoding.\n", encoding); + fprintf(stderr, + " NSISOLatin1StringEncoding set as default.\n"); + defEnc = NSISOLatin1StringEncoding; + } + + if (natEnc == GSUndefinedEncoding) + { + natEnc = defEnc; + } + + [local_lock unlock]; + } + return defEnc; +} + +NSString* +GSPrivateEncodingName(NSStringEncoding encoding) +{ + if (GSPrivateIsEncodingSupported(encoding) == NO) + { + return @"Unknown encoding"; + } + return [NSString stringWithUTF8String: encodingTable[encoding]->ename]; +} + +BOOL +GSPrivateIsByteEncoding(NSStringEncoding encoding) +{ + if (GSPrivateIsEncodingSupported(encoding) == NO) + { + return NO; + } + return encodingTable[encoding]->eightBit; +} + +NSStringEncoding +GSPrivateNativeCStringEncoding() +{ + if (natEnc == GSUndefinedEncoding) + { + /* GSPrivateDefaultCStringEncoding() will actually set the encoding. + */ + GSPrivateDefaultCStringEncoding(); + } + return natEnc; +} + diff --git a/Headers/Additions/GNUstepBase/unicode/caseconv.h b/Source/Additions/unicode/caseconv.h similarity index 98% rename from Headers/Additions/GNUstepBase/unicode/caseconv.h rename to Source/Additions/unicode/caseconv.h index b7754b9b1..e1107bfa0 100644 --- a/Headers/Additions/GNUstepBase/unicode/caseconv.h +++ b/Source/Additions/unicode/caseconv.h @@ -8,7 +8,7 @@ are permitted in any medium without royalty provided the copyright notice and this notice are preserved. */ -unichar gs_casemap_empty_table[] = { +static unichar gs_casemap_empty_table[] = { 0x0, 0x0, 0x0, @@ -267,7 +267,7 @@ unichar gs_casemap_empty_table[] = { 0x0, }; -unichar gs_tolower_map_table_0[] = { +static unichar gs_tolower_map_table_0[] = { 0x0, 0x0, 0x0, @@ -525,7 +525,8 @@ unichar gs_tolower_map_table_0[] = { 0x0, 0x0, }; -unichar gs_tolower_map_table_1[] = { + +static unichar gs_tolower_map_table_1[] = { 0x101, /* 0 */ 0x0, 0x103, /* 2 */ @@ -783,7 +784,8 @@ unichar gs_tolower_map_table_1[] = { 0x1ff, /* fe */ 0x0, }; -unichar gs_tolower_map_table_2[] = { + +static unichar gs_tolower_map_table_2[] = { 0x201, /* 0 */ 0x0, 0x203, /* 2 */ @@ -1041,7 +1043,8 @@ unichar gs_tolower_map_table_2[] = { 0x0, 0x0, }; -unichar gs_tolower_map_table_3[] = { + +static unichar gs_tolower_map_table_3[] = { 0x0, 0x0, 0x0, @@ -1299,7 +1302,8 @@ unichar gs_tolower_map_table_3[] = { 0x0, 0x0, }; -unichar gs_tolower_map_table_4[] = { + +static unichar gs_tolower_map_table_4[] = { 0x450, /* 0 */ 0x451, /* 1 */ 0x452, /* 2 */ @@ -1557,7 +1561,8 @@ unichar gs_tolower_map_table_4[] = { 0x0, 0x0, }; -unichar gs_tolower_map_table_5[] = { + +static unichar gs_tolower_map_table_5[] = { 0x0, 0x0, 0x0, @@ -1815,7 +1820,8 @@ unichar gs_tolower_map_table_5[] = { 0x0, 0x0, }; -unichar gs_tolower_map_table_1e[] = { + +static unichar gs_tolower_map_table_1e[] = { 0x1e01, /* 0 */ 0x0, 0x1e03, /* 2 */ @@ -2073,7 +2079,8 @@ unichar gs_tolower_map_table_1e[] = { 0x0, 0x0, }; -unichar gs_tolower_map_table_1f[] = { + +static unichar gs_tolower_map_table_1f[] = { 0x0, 0x0, 0x0, @@ -2331,7 +2338,8 @@ unichar gs_tolower_map_table_1f[] = { 0x0, 0x0, }; -unichar gs_tolower_map_table_21[] = { + +static unichar gs_tolower_map_table_21[] = { 0x0, 0x0, 0x0, @@ -2589,7 +2597,8 @@ unichar gs_tolower_map_table_21[] = { 0x0, 0x0, }; -unichar gs_tolower_map_table_24[] = { + +static unichar gs_tolower_map_table_24[] = { 0x0, 0x0, 0x0, @@ -2847,7 +2856,8 @@ unichar gs_tolower_map_table_24[] = { 0x0, 0x0, }; -unichar gs_tolower_map_table_ff[] = { + +static unichar gs_tolower_map_table_ff[] = { 0x0, 0x0, 0x0, @@ -3106,7 +3116,7 @@ unichar gs_tolower_map_table_ff[] = { 0x0, }; -unichar *gs_tolower_map[] = { +static unichar *gs_tolower_map[] = { gs_tolower_map_table_0, gs_tolower_map_table_1, gs_tolower_map_table_2, @@ -3365,7 +3375,7 @@ unichar *gs_tolower_map[] = { gs_tolower_map_table_ff, }; -unichar gs_toupper_map_table_0[] = { +static unichar gs_toupper_map_table_0[] = { 0x0, 0x0, 0x0, @@ -3624,7 +3634,7 @@ unichar gs_toupper_map_table_0[] = { 0x178, /* ff */ }; -unichar gs_toupper_map_table_1[] = { +static unichar gs_toupper_map_table_1[] = { 0x0, 0x100, /* 1 */ 0x0, @@ -3883,7 +3893,7 @@ unichar gs_toupper_map_table_1[] = { 0x1fe, /* ff */ }; -unichar gs_toupper_map_table_2[] = { +static unichar gs_toupper_map_table_2[] = { 0x0, 0x200, /* 1 */ 0x0, @@ -4142,7 +4152,7 @@ unichar gs_toupper_map_table_2[] = { 0x0, }; -unichar gs_toupper_map_table_3[] = { +static unichar gs_toupper_map_table_3[] = { 0x0, 0x0, 0x0, @@ -4401,7 +4411,7 @@ unichar gs_toupper_map_table_3[] = { 0x0, }; -unichar gs_toupper_map_table_4[] = { +static unichar gs_toupper_map_table_4[] = { 0x0, 0x0, 0x0, @@ -4660,7 +4670,7 @@ unichar gs_toupper_map_table_4[] = { 0x0, }; -unichar gs_toupper_map_table_5[] = { +static unichar gs_toupper_map_table_5[] = { 0x0, 0x0, 0x0, @@ -4919,31 +4929,7 @@ unichar gs_toupper_map_table_5[] = { 0x0, }; - - - - - - - - - - - - - - - - - - - - - - - - -unichar gs_toupper_map_table_1e[] = { +static unichar gs_toupper_map_table_1e[] = { 0x0, 0x1e00, /* 1 */ 0x0, @@ -5202,7 +5188,7 @@ unichar gs_toupper_map_table_1e[] = { 0x0, }; -unichar gs_toupper_map_table_1f[] = { +static unichar gs_toupper_map_table_1f[] = { 0x1f08, /* 0 */ 0x1f09, /* 1 */ 0x1f0a, /* 2 */ @@ -5461,8 +5447,7 @@ unichar gs_toupper_map_table_1f[] = { 0x0, }; - -unichar gs_toupper_map_table_21[] = { +static unichar gs_toupper_map_table_21[] = { 0x0, 0x0, 0x0, @@ -5721,9 +5706,7 @@ unichar gs_toupper_map_table_21[] = { 0x0, }; - - -unichar gs_toupper_map_table_24[] = { +static unichar gs_toupper_map_table_24[] = { 0x0, 0x0, 0x0, @@ -5982,225 +5965,7 @@ unichar gs_toupper_map_table_24[] = { 0x0, }; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -unichar gs_toupper_map_table_ff[] = { +static unichar gs_toupper_map_table_ff[] = { 0x0, 0x0, 0x0, @@ -6459,8 +6224,7 @@ unichar gs_toupper_map_table_ff[] = { 0x0, }; - -unichar *gs_toupper_map[] = { +static unichar *gs_toupper_map[] = { gs_toupper_map_table_0, gs_toupper_map_table_1, gs_toupper_map_table_2, diff --git a/Headers/Additions/GNUstepBase/unicode/cop.h b/Source/Additions/unicode/cop.h similarity index 98% rename from Headers/Additions/GNUstepBase/unicode/cop.h rename to Source/Additions/unicode/cop.h index 7d74be7d1..5e80ea872 100644 --- a/Headers/Additions/GNUstepBase/unicode/cop.h +++ b/Source/Additions/unicode/cop.h @@ -9,9 +9,9 @@ struct _cop_ {unichar code; unsigned char cop;}; -const unsigned int uni_cop_table_size = 355; -struct _cop_ uni_cop_table[]= +static const unsigned int uni_cop_table_size = 355; +static struct _cop_ uni_cop_table[]= { {0x0300,230}, {0x0301,230}, diff --git a/Headers/Additions/GNUstepBase/unicode/cyrillic.h b/Source/Additions/unicode/cyrillic.h similarity index 94% rename from Headers/Additions/GNUstepBase/unicode/cyrillic.h rename to Source/Additions/unicode/cyrillic.h index 4096eb2d1..7facce19d 100644 --- a/Headers/Additions/GNUstepBase/unicode/cyrillic.h +++ b/Source/Additions/unicode/cyrillic.h @@ -8,9 +8,8 @@ */ -const unsigned int Cyrillic_conv_base = 0x80; - -unichar Cyrillic_char_to_uni_table[] = +static const unsigned int Cyrillic_conv_base = 0x80; +static unichar Cyrillic_char_to_uni_table[] = { 0x0080, 0x0081, @@ -144,9 +143,8 @@ unichar Cyrillic_char_to_uni_table[] = // Unicode to ISO_8859-5,1988 maping -const unsigned int Cyrillic_uni_to_char_table_size = 128; - -_ucc_ Cyrillic_uni_to_char_table[]= +static const unsigned int Cyrillic_uni_to_char_table_size = 128; +static _ucc_ Cyrillic_uni_to_char_table[]= { {0x0080,0x80}, {0x0081,0x81}, diff --git a/Headers/Additions/GNUstepBase/unicode/decomp.h b/Source/Additions/unicode/decomp.h similarity index 99% rename from Headers/Additions/GNUstepBase/unicode/decomp.h rename to Source/Additions/unicode/decomp.h index 1b94a6881..54c8919ad 100644 --- a/Headers/Additions/GNUstepBase/unicode/decomp.h +++ b/Source/Additions/unicode/decomp.h @@ -9,9 +9,9 @@ struct _dec_ {unichar code; unichar decomp[5];}; -const unsigned int uni_dec_table_size = 1052; -struct _dec_ uni_dec_table[]= +static const unsigned int uni_dec_table_size = 1052; +static struct _dec_ uni_dec_table[]= { {0x00C0, {0x0041, 0x0300, 0}}, {0x00C1, {0x0041, 0x0301, 0}}, diff --git a/Headers/Additions/GNUstepBase/unicode/gsm0338.h b/Source/Additions/unicode/gsm0338.h similarity index 96% rename from Headers/Additions/GNUstepBase/unicode/gsm0338.h rename to Source/Additions/unicode/gsm0338.h index d9c164772..af7d8e21a 100644 --- a/Headers/Additions/GNUstepBase/unicode/gsm0338.h +++ b/Source/Additions/unicode/gsm0338.h @@ -10,9 +10,8 @@ // GSM0338 to Unicode maping -const unsigned int GSM0338_conv_base = 0x00; - -unichar GSM0338_char_to_uni_table[] = +static const unsigned int GSM0338_conv_base = 0x00; +static unichar GSM0338_char_to_uni_table[] = { 0x0040, 0x00A3, @@ -144,7 +143,7 @@ unichar GSM0338_char_to_uni_table[] = 0x00E0 }; -_ucc_ GSM0338_uni_to_char_table[] = +static _ucc_ GSM0338_uni_to_char_table[] = { {0x000A,0x0A,}, {0x000D,0x0D,}, @@ -277,7 +276,7 @@ _ucc_ GSM0338_uni_to_char_table[] = }; #define GSM0338_tsize (sizeof(GSM0338_uni_to_char_table)/sizeof(_ucc_)) -_ucc_ GSM0338_escapes[] = +static _ucc_ GSM0338_escapes[] = { {0x000C,0x0A}, /* Form feed */ {0x005B,0x3C}, /* '[' */ @@ -300,7 +299,7 @@ _ucc_ GSM0338_escapes[] = * a cut down version suitable for use when delivering data to phones * which don't support escape sequences. */ -_ucc_ GSM0338_lossy[] = +static _ucc_ GSM0338_lossy[] = { {0x005B,0x3C}, /* '[' => '<' */ {0x005C,0x2F}, /* '\\' => '/' */ diff --git a/Headers/Additions/GNUstepBase/unicode/latin2.h b/Source/Additions/unicode/latin2.h similarity index 95% rename from Headers/Additions/GNUstepBase/unicode/latin2.h rename to Source/Additions/unicode/latin2.h index 743d57e04..df7e18f0f 100644 --- a/Headers/Additions/GNUstepBase/unicode/latin2.h +++ b/Source/Additions/unicode/latin2.h @@ -10,9 +10,8 @@ // ISO_8859-2 to Unicode maping -const unsigned int Latin2_conv_base = 0x80; - -unichar Latin2_char_to_uni_table[] = +static const unsigned int Latin2_conv_base = 0x80; +static unichar Latin2_char_to_uni_table[] = { 0x0080, 0x0081, @@ -146,9 +145,8 @@ unichar Latin2_char_to_uni_table[] = // Unicode to ISO_8859-2 maping -const unsigned int Latin2_uni_to_char_table_size = 128; - -_ucc_ Latin2_uni_to_char_table[]= +static const unsigned int Latin2_uni_to_char_table_size = 128; +static _ucc_ Latin2_uni_to_char_table[]= { {0x0080,0x80}, {0x0081,0x81}, diff --git a/Headers/Additions/GNUstepBase/unicode/latin9.h b/Source/Additions/unicode/latin9.h similarity index 95% rename from Headers/Additions/GNUstepBase/unicode/latin9.h rename to Source/Additions/unicode/latin9.h index 8f3b36419..7826cbcbb 100644 --- a/Headers/Additions/GNUstepBase/unicode/latin9.h +++ b/Source/Additions/unicode/latin9.h @@ -10,9 +10,8 @@ // ISO_8859-15 to Unicode maping -const unsigned int Latin9_conv_base = 0x80; - -unichar Latin9_char_to_uni_table[] = +static const unsigned int Latin9_conv_base = 0x80; +static unichar Latin9_char_to_uni_table[] = { 0x0080, 0x0081, @@ -146,9 +145,8 @@ unichar Latin9_char_to_uni_table[] = // Unicode to ISO_8859-15 maping -const unsigned int Latin9_uni_to_char_table_size = 128; - -_ucc_ Latin9_uni_to_char_table[]= +static const unsigned int Latin9_uni_to_char_table_size = 128; +static _ucc_ Latin9_uni_to_char_table[]= { {0x0080, 0x80}, {0x0081, 0x81}, diff --git a/Headers/Additions/GNUstepBase/unicode/nextstep.h b/Source/Additions/unicode/nextstep.h similarity index 94% rename from Headers/Additions/GNUstepBase/unicode/nextstep.h rename to Source/Additions/unicode/nextstep.h index 979ae6201..95c881a9f 100644 --- a/Headers/Additions/GNUstepBase/unicode/nextstep.h +++ b/Source/Additions/unicode/nextstep.h @@ -7,8 +7,8 @@ notice and this notice are preserved. */ -const unsigned int Next_conv_base = 0x80; -unichar Next_char_to_uni_table[] = +static const unsigned int Next_conv_base = 0x80; +static unichar Next_char_to_uni_table[] = { 0x00A0, 0x00C0, @@ -135,9 +135,8 @@ unichar Next_char_to_uni_table[] = // Unicode to NextStep maping -const unsigned int Next_uni_to_char_table_size = 128; - -_ucc_ Next_uni_to_char_table[]= +static const unsigned int Next_uni_to_char_table_size = 128; +static _ucc_ Next_uni_to_char_table[]= { {0x00A0,0x80}, {0x00A1,0xA1}, diff --git a/Headers/Additions/GNUstepBase/unicode/thai.h b/Source/Additions/unicode/thai.h similarity index 93% rename from Headers/Additions/GNUstepBase/unicode/thai.h rename to Source/Additions/unicode/thai.h index 54b6c259a..ddcae5935 100644 --- a/Headers/Additions/GNUstepBase/unicode/thai.h +++ b/Source/Additions/unicode/thai.h @@ -8,9 +8,8 @@ */ -const unsigned int Thai_conv_base = 0xA0; - -unichar Thai_char_to_uni_table[] = +static const unsigned int Thai_conv_base = 0xA0; +static unichar Thai_char_to_uni_table[] = { 0x00A0, 0x0E01, @@ -112,9 +111,8 @@ unichar Thai_char_to_uni_table[] = /* Unicode to ISO_8859-11 maping */ -const unsigned int Thai_uni_to_char_table_size = 88; - -_ucc_ Thai_uni_to_char_table[]= +static const unsigned int Thai_uni_to_char_table_size = 88; +static _ucc_ Thai_uni_to_char_table[]= { {0x00A0,0xA0}, {0x0E01,0xA1}, diff --git a/Source/DocMakefile b/Source/DocMakefile index 5dc814719..897e34bb7 100644 --- a/Source/DocMakefile +++ b/Source/DocMakefile @@ -75,6 +75,7 @@ NSKeyValueObserving.h \ NSLock.h \ NSMapTable.h \ NSMethodSignature.h \ +NSNetServices.h \ NSNotification.h \ NSNotificationQueue.h \ NSNull.h \ @@ -117,6 +118,7 @@ NSURLRequest.h \ NSURLResponse.h \ NSUserDefaults.h \ NSValue.h \ +NSValueTransformer.h \ NSXMLParser.h \ NSZone.h @@ -131,8 +133,8 @@ GSLock.h \ GSMime.h \ GSObjCRuntime.h \ GSUnion.h \ +GSVersionMacros.h \ GSXML.h \ -GSFunctions.h \ behavior.h \ Unicode.h \ GCObject.h \ diff --git a/Source/GNUmakefile b/Source/GNUmakefile index accff0355..7b08148a4 100644 --- a/Source/GNUmakefile +++ b/Source/GNUmakefile @@ -23,18 +23,27 @@ # Boston, MA 02111 USA. # +ifeq ($(GNUSTEP_MAKEFILES),) + GNUSTEP_MAKEFILES := $(shell gnustep-config --variable=GNUSTEP_MAKEFILES 2>/dev/null) +endif + +ifeq ($(GNUSTEP_MAKEFILES),) + $(error You need to set GNUSTEP_MAKEFILES before compiling!) +endif + # Install into the system root by default -GNUSTEP_INSTALLATION_DIR = $(GNUSTEP_SYSTEM_ROOT) +GNUSTEP_INSTALLATION_DOMAIN = SYSTEM GNUSTEP_LOCAL_ADDITIONAL_MAKEFILES=../base.make + include $(GNUSTEP_MAKEFILES)/common.make include ../Version include ../config.mak # Interface version changes with each minor release -libgnustep-base_INTERFACE_VERSION=${MAJOR_VERSION}.${MINOR_VERSION} -libgnustep-baseadd_INTERFACE_VERSION=${MAJOR_VERSION}.${MINOR_VERSION} +libgnustep-base_INTERFACE_VERSION=$(MAJOR_VERSION).$(MINOR_VERSION) +libgnustep-baseadd_INTERFACE_VERSION=$(MAJOR_VERSION).$(MINOR_VERSION) PACKAGE_NAME = gnustep-base @@ -62,16 +71,15 @@ ifeq ($(GNUSTEP_TARGET_OS), mingw32) DEFS= -DGNUSTEP_TARGET_DIR=\"$(GNUSTEP_TARGET_DIR)\" \ -DGNUSTEP_TARGET_CPU=\"$(GNUSTEP_TARGET_CPU)\" \ -DGNUSTEP_TARGET_OS=\"$(GNUSTEP_TARGET_OS)\" \ - -DGNUSTEP_FLATTENED=\"$(GNUSTEP_FLATTENED)\" \ + -DGNUSTEP_IS_FLATTENED=\"$(GNUSTEP_IS_FLATTENED)\" \ -DLIBRARY_COMBO=\"$(LIBRARY_COMBO)\" - else DEFS= -DGNUSTEP_TARGET_DIR=\"$(GNUSTEP_TARGET_DIR)\" \ -DGNUSTEP_TARGET_CPU=\"$(GNUSTEP_TARGET_CPU)\" \ -DGNUSTEP_TARGET_OS=\"$(GNUSTEP_TARGET_OS)\" \ - -DGNUSTEP_FLATTENED=\"$(GNUSTEP_FLATTENED)\" \ + -DGNUSTEP_IS_FLATTENED=\"$(GNUSTEP_IS_FLATTENED)\" \ -DLIBRARY_COMBO=\"$(LIBRARY_COMBO)\" endif @@ -79,7 +87,6 @@ endif # The GNU source files GNU_MFILES = \ -GSCompatibility.m \ GSLocale.m \ preface.m \ mframe.m @@ -108,6 +115,7 @@ win32-def.top \ libgnustep-base.def ADD_HEADERS = \ +GSVersionMacros.h \ GSObjCRuntime.h \ GSCategories.h \ GSFileHandle.h \ @@ -145,10 +153,11 @@ GSSet.m \ GSStream.m \ GSString.m \ GSValue.m \ -NSAttributedString.m \ +NSAffineTransform.m \ NSArchiver.m \ NSArray.m \ NSAssertionHandler.m \ +NSAttributedString.m \ NSAutoreleasePool.m \ NSBundle.m \ NSCachedURLResponse.m \ @@ -221,6 +230,7 @@ NSSet.m \ NSSocketPort.m \ NSSocketPortNameServer.m \ NSSortDescriptor.m \ +NSSpellServer.m \ NSString.m \ NSTask.m \ NSThread.m \ @@ -242,6 +252,7 @@ NSURLResponse.m \ NSURLHandle.m \ NSUserDefaults.m \ NSValue.m \ +NSValueTransformer.m \ NSXMLParser.m \ NSZone.m \ externs.m \ @@ -253,6 +264,11 @@ BASE_MFILES += \ GSFileHandle.m \ NSMessagePort.m \ NSMessagePortNameServer.m + +ifeq ($(GNUSTEP_BASE_HAVE_MDNS), 1) +BASE_MFILES += NSNetServices.m +endif + endif ifeq ($(WITH_FFI),libffi) @@ -278,6 +294,7 @@ tzfile.h FOUNDATION_HEADERS = \ Foundation.h \ +NSAffineTransform.h \ NSArchiver.h \ NSArray.h \ NSAttributedString.h \ @@ -322,6 +339,7 @@ NSKeyValueObserving.h \ NSLock.h \ NSMapTable.h \ NSMethodSignature.h \ +NSNetServices.h \ NSNotification.h \ NSNotificationQueue.h \ NSNull.h \ @@ -344,6 +362,7 @@ NSScanner.h \ NSSerialization.h \ NSSet.h \ NSSortDescriptor.h \ +NSSpellServer.h \ NSStream.h \ NSString.h \ NSTask.h \ @@ -367,27 +386,19 @@ NSURLResponse.h \ NSUserDefaults.h \ NSUtilities.h \ NSValue.h \ +NSValueTransformer.h \ NSXMLParser.h \ NSZone.h -UNICODE_HEADERS = \ -unicode/caseconv.h \ -unicode/cop.h \ -unicode/cyrillic.h \ -unicode/latin2.h \ -unicode/decomp.h \ -unicode/nextstep.h - HEADERS_INSTALL = $(GNU_HEADERS) \ - $(FOUNDATION_HEADERS) \ - $(UNICODE_HEADERS) + $(FOUNDATION_HEADERS) GENERATED_HFILES = \ dynamic-load.h \ $(HEADER_DIR_BASE)/preface.h \ $(GNUSTEP_TARGET_DIR)/mframe.h \ $(GNUSTEP_TARGET_DIR)/config.h \ -$(GNUSTEP_TARGET_DIR)/GSConfig.h +$(GNUSTEP_TARGET_DIR)/GNUstepBase/GSConfig.h ifeq ($(HAVE_INET_PTON), no) GNU_CFILES += inet_pton.c @@ -408,7 +419,12 @@ libgnustep-base_HEADER_FILES = $(FOUNDATION_HEADERS) # Resources RESOURCE_SET_NAME = libbase-resources -libbase-resources_RESOURCE_FILES_INSTALL_DIR = Library/Libraries/Resources/gnustep-base + +# This is for gnustep-make >= 14-02-2007 +libbase-resources_INSTALL_DIR = $(GNUSTEP_LIBRARY)/Libraries/gnustep-base/Versions/$(libgnustep-base_INTERFACE_VERSION)/Resources +# This is kept temporarily for gnustep-make < 14-02-2007 +libbase-resources_RESOURCE_FILES_INSTALL_DIR = /Library/Libraries/Resources/gnustep-base + libbase-resources_LANGUAGES = libbase-resources_LOCALIZED_RESOURCE_FILES = libbase-resources_RESOURCE_DIRS = diff --git a/Source/GSArray.m b/Source/GSArray.m index b4a9ec3b4..adb6c534e 100644 --- a/Source/GSArray.m +++ b/Source/GSArray.m @@ -36,6 +36,8 @@ // For private method _decodeArrayOfObjectsForKey: #include "Foundation/NSKeyedArchiver.h" +#include "GSPrivate.h" + static SEL eqSel; static SEL oaiSel; @@ -54,39 +56,10 @@ static Class GSInlineArrayClass; @interface GSArrayEnumeratorReverse : GSArrayEnumerator @end - -@interface GSArray : NSArray -{ -@public - id *_contents_array; - unsigned _count; -} -@end - -@interface GSInlineArray : GSArray -{ -} -@end - -@interface GSMutableArray : NSMutableArray -{ -@public - id *_contents_array; - unsigned _count; - unsigned _capacity; - int _grow_factor; -} -@end - @interface GSMutableArray (GSArrayBehavior) - (void) _raiseRangeExceptionWithIndex: (unsigned)index from: (SEL)sel; @end -@interface GSPlaceholderArray : NSArray -{ -} -@end - @implementation GSArray - (void) _raiseRangeExceptionWithIndex: (unsigned)index from: (SEL)sel diff --git a/Source/GSCompatibility.m b/Source/GSCompatibility.m deleted file mode 100644 index 9728439a4..000000000 --- a/Source/GSCompatibility.m +++ /dev/null @@ -1,61 +0,0 @@ -/** Runtime MacOSX compatibility functionality - Copyright (C) 2000 Free Software Foundation, Inc. - - Written by: Richard Frith-Macdonald - Date: August 2000 - - 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., 51 Franklin Street, Fifth Floor, Boston, MA 02111 USA. - */ - -#include "config.h" -#include "Foundation/Foundation.h" -#include "Foundation/NSDebug.h" - -#include "GSPrivate.h" - -@class GSMutableString; - -#ifndef HAVE_RINT -#include -static double rint(double a) -{ - return (floor(a+0.5)); -} -#endif - -/* - * Runtime MacOS-X compatibility flags. - */ - -BOOL GSMacOSXCompatibleGeometry(void) -{ - if (GSUserDefaultsFlag(GSOldStyleGeometry) == YES) - return NO; - return GSUserDefaultsFlag(GSMacOSXCompatible); -} - -BOOL GSMacOSXCompatiblePropertyLists(void) -{ -#if defined(HAVE_LIBXML) - if (GSUserDefaultsFlag(NSWriteOldStylePropertyLists) == YES) - return NO; - return GSUserDefaultsFlag(GSMacOSXCompatible); -#else - return NO; -#endif -} - diff --git a/Source/GSConcreteValue.m b/Source/GSConcreteValue.m index f02b550fe..1665d1ee6 100644 --- a/Source/GSConcreteValue.m +++ b/Source/GSConcreteValue.m @@ -18,7 +18,8 @@ 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., 51 Franklin Street, Fifth Floor, Boston, MA 02111 USA. + Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02111 USA. */ #include "config.h" diff --git a/Source/GSConcreteValueTemplate.m b/Source/GSConcreteValueTemplate.m index 4a4596925..60e82fe6f 100644 --- a/Source/GSConcreteValueTemplate.m +++ b/Source/GSConcreteValueTemplate.m @@ -19,7 +19,8 @@ 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., 51 Franklin Street, Fifth Floor, Boston, MA 02111 USA. + Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02111 USA. */ diff --git a/Source/GSCountedSet.m b/Source/GSCountedSet.m index 7fa3a140f..ef96f00c7 100644 --- a/Source/GSCountedSet.m +++ b/Source/GSCountedSet.m @@ -18,7 +18,8 @@ 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., 51 Franklin Street, Fifth Floor, Boston, MA 02111 USA. + Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02111 USA. */ #include "config.h" diff --git a/Source/GSDictionary.m b/Source/GSDictionary.m index 07789b3ff..1e23a8118 100644 --- a/Source/GSDictionary.m +++ b/Source/GSDictionary.m @@ -18,7 +18,8 @@ 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., 51 Franklin Street, Fifth Floor, Boston, MA 02111 USA. + Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02111 USA. */ diff --git a/Source/GSFFCallInvocation.m b/Source/GSFFCallInvocation.m index bc491be9e..c542004d1 100644 --- a/Source/GSFFCallInvocation.m +++ b/Source/GSFFCallInvocation.m @@ -141,7 +141,7 @@ static objc_mutex_t ff_callback_map_lock = NULL; static vacallReturnTypeInfo returnTypeInfo [STATIC_CALLBACK_LIST_SIZE]; /* Function that implements the actual forwarding */ -void +static void GSInvocationCallback(void *callback_data, va_alist args); /* @@ -168,7 +168,7 @@ gs_offset(const char *type, int index) /* Determines if the structure type can be returned entirely in registers. See the avcall or vacall man pages for more info. FIXME: I'm betting this won't work if a structure contains another structure */ -int +static int gs_splittable (const char *type) { int i, numtypes; @@ -297,7 +297,7 @@ gs_find_by_receiver_best_typed_sel (id receiver, SEL sel) Only passes the first part. Is used for determining the return type for the vacall macros. */ -void +static void gs_sel_type_to_callback_type (const char *sel_type, vacallReturnTypeInfo *vatype) { @@ -771,7 +771,7 @@ gs_protocol_selector(const char *types) * information. */ -void +static void GSInvocationCallback (void *callback_data, va_alist args) { id obj; diff --git a/Source/GSFFIInvocation.m b/Source/GSFFIInvocation.m index 58d183c10..7f55423b0 100644 --- a/Source/GSFFIInvocation.m +++ b/Source/GSFFIInvocation.m @@ -18,7 +18,8 @@ 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., 51 Franklin Street, Fifth Floor, Boston, MA 02111 USA. + Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02111 USA. */ #include "Foundation/NSException.h" #include "Foundation/NSCoder.h" @@ -44,7 +45,7 @@ typedef void (*ffi_closure_fun) (ffi_cif*,void*,void**,void*); typedef void (*f_fun) (); -void GSFFIInvocationCallback(ffi_cif*, void*, void **, void*); +static void GSFFIInvocationCallback(ffi_cif*, void*, void **, void*); /* * If we are using the GNU ObjC runtime we could @@ -407,7 +408,7 @@ gs_protocol_selector(const char *types) return NO; } -void +static void GSFFIInvocationCallback(ffi_cif *cif, void *retp, void **args, void *user) { id obj; diff --git a/Source/GSFTPURLHandle.m b/Source/GSFTPURLHandle.m index 64d5a035e..b029e8ec9 100644 --- a/Source/GSFTPURLHandle.m +++ b/Source/GSFTPURLHandle.m @@ -18,7 +18,8 @@ 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., 51 Franklin Street, Fifth Floor, Boston, MA 02111 USA. + Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02111 USA. */ #include "config.h" @@ -36,6 +37,7 @@ #include "Foundation/NSFileHandle.h" #include "Foundation/NSDebug.h" #include "GNUstepBase/GSMime.h" +#include "GSPrivate.h" GS_EXPORT NSString * const GSTelnetNotification; GS_EXPORT NSString * const GSTelnetErrorKey; @@ -972,14 +974,12 @@ static NSLock *urlLock = nil; protocol: @"tcp"]; if (sock == nil) { - extern int errno; - /* * Tell superclass that the load failed - let it do housekeeping. */ [self backgroundLoadDidFailWithReason: [NSString stringWithFormat: - @"Unable to connect to %@:%@ ... %s", - host, port, GSLastErrorStr(errno)]]; + @"Unable to connect to %@:%@ ... %@", + host, port, [NSError _last]]]; return; } cHandle = [[GSTelnetHandle alloc] initWithHandle: sock isConnected: NO]; diff --git a/Source/GSFileHandle.m b/Source/GSFileHandle.m index 94523c5a9..ba5c4efb5 100644 --- a/Source/GSFileHandle.m +++ b/Source/GSFileHandle.m @@ -42,6 +42,7 @@ #include "Foundation/NSProcessInfo.h" #include "Foundation/NSUserDefaults.h" #include "Foundation/NSDebug.h" +#include "GSPrivate.h" #include "../Tools/gdomap.h" @@ -797,7 +798,7 @@ NSString * const GSSOCKSRecvAddr = @"GSSOCKSRecvAddr"; if ((net = socket(AF_INET, SOCK_STREAM, PF_UNSPEC)) == -1) { - NSLog(@"unable to create socket - %s", GSLastErrorStr(errno)); + NSLog(@"unable to create socket - %@", [NSError _last]); RELEASE(self); return nil; } @@ -811,8 +812,8 @@ NSString * const GSSOCKSRecvAddr = @"GSSOCKSRecvAddr"; { if (bind(net, (struct sockaddr *)&lsin, sizeof(lsin)) == -1) { - NSLog(@"unable to bind to port %s:%d - %s", inet_ntoa(lsin.sin_addr), - GSSwapBigI16ToHost(sin.sin_port), GSLastErrorStr(errno)); + NSLog(@"unable to bind to port %s:%d - %@", inet_ntoa(lsin.sin_addr), + GSSwapBigI16ToHost(sin.sin_port), [NSError _last]); (void) close(net); RELEASE(self); return nil; @@ -830,9 +831,9 @@ NSString * const GSSOCKSRecvAddr = @"GSSOCKSRecvAddr"; { if (errno != EINPROGRESS) { - NSLog(@"unable to make connection to %s:%d - %s", + NSLog(@"unable to make connection to %s:%d - %@", inet_ntoa(sin.sin_addr), - GSSwapBigI16ToHost(sin.sin_port), GSLastErrorStr(errno)); + GSSwapBigI16ToHost(sin.sin_port), [NSError _last]); RELEASE(self); return nil; } @@ -896,7 +897,7 @@ NSString * const GSSOCKSRecvAddr = @"GSSOCKSRecvAddr"; if ((net = socket(AF_INET, SOCK_STREAM, PF_UNSPEC)) == -1) { - NSLog(@"unable to create socket - %s", GSLastErrorStr(errno)); + NSLog(@"unable to create socket - %@", [NSError _last]); RELEASE(self); return nil; } @@ -913,8 +914,8 @@ NSString * const GSSOCKSRecvAddr = @"GSSOCKSRecvAddr"; if (bind(net, (struct sockaddr *)&sin, sizeof(sin)) == -1) { - NSLog(@"unable to bind to port %s:%d - %s", inet_ntoa(sin.sin_addr), - GSSwapBigI16ToHost(sin.sin_port), GSLastErrorStr(errno)); + NSLog(@"unable to bind to port %s:%d - %@", inet_ntoa(sin.sin_addr), + GSSwapBigI16ToHost(sin.sin_port), [NSError _last]); (void) close(net); RELEASE(self); return nil; @@ -922,7 +923,7 @@ NSString * const GSSOCKSRecvAddr = @"GSSOCKSRecvAddr"; if (listen(net, 256) == -1) { - NSLog(@"unable to listen on port - %s", GSLastErrorStr(errno)); + NSLog(@"unable to listen on port - %@", [NSError _last]); (void) close(net); RELEASE(self); return nil; @@ -930,7 +931,7 @@ NSString * const GSSOCKSRecvAddr = @"GSSOCKSRecvAddr"; if (getsockname(net, (struct sockaddr*)&sin, &size) == -1) { - NSLog(@"unable to get socket name - %s", GSLastErrorStr(errno)); + NSLog(@"unable to get socket name - %@", [NSError _last]); (void) close(net); RELEASE(self); return nil; @@ -1095,8 +1096,8 @@ NSString * const GSSOCKSRecvAddr = @"GSSOCKSRecvAddr"; if (fstat(desc, &sbuf) < 0) { - NSLog(@"unable to get status of descriptor %d - %s", - desc, GSLastErrorStr(errno)); + NSLog(@"unable to get status of descriptor %d - %@", + desc, [NSError _last]); } else { @@ -1317,8 +1318,8 @@ NSString * const GSSOCKSRecvAddr = @"GSSOCKSRecvAddr"; if (len < 0) { [NSException raise: NSFileHandleOperationException - format: @"unable to read from descriptor - %s", - GSLastErrorStr(errno)]; + format: @"unable to read from descriptor - %@", + [NSError _last]]; } return d; } @@ -1342,8 +1343,8 @@ NSString * const GSSOCKSRecvAddr = @"GSSOCKSRecvAddr"; if (len < 0) { [NSException raise: NSFileHandleOperationException - format: @"unable to read from descriptor - %s", - GSLastErrorStr(errno)]; + format: @"unable to read from descriptor - %@", + [NSError _last]]; } return d; } @@ -1368,8 +1369,8 @@ NSString * const GSSOCKSRecvAddr = @"GSSOCKSRecvAddr"; if (got < 0) { [NSException raise: NSFileHandleOperationException - format: @"unable to read from descriptor - %s", - GSLastErrorStr(errno)]; + format: @"unable to read from descriptor - %@", + [NSError _last]]; } [d setLength: got]; } @@ -1391,8 +1392,8 @@ NSString * const GSSOCKSRecvAddr = @"GSSOCKSRecvAddr"; else if (got < 0) { [NSException raise: NSFileHandleOperationException - format: @"unable to read from descriptor - %s", - GSLastErrorStr(errno)]; + format: @"unable to read from descriptor - %@", + [NSError _last]]; } } while (len > 0 && got > 0); @@ -1437,8 +1438,8 @@ NSString * const GSSOCKSRecvAddr = @"GSSOCKSRecvAddr"; if (rval < 0) { [NSException raise: NSFileHandleOperationException - format: @"unable to write to descriptor - %s", - GSLastErrorStr(errno)]; + format: @"unable to write to descriptor - %@", + [NSError _last]]; } } @@ -1543,8 +1544,8 @@ NSString * const GSSOCKSRecvAddr = @"GSSOCKSRecvAddr"; if (result < 0) { [NSException raise: NSFileHandleOperationException - format: @"failed to move to offset in file - %s", - GSLastErrorStr(errno)]; + format: @"failed to move to offset in file - %@", + [NSError _last]]; } return (unsigned long long)result; } @@ -1567,8 +1568,8 @@ NSString * const GSSOCKSRecvAddr = @"GSSOCKSRecvAddr"; if (result < 0) { [NSException raise: NSFileHandleOperationException - format: @"failed to move to offset in file - %s", - GSLastErrorStr(errno)]; + format: @"failed to move to offset in file - %@", + [NSError _last]]; } return (unsigned long long)result; } @@ -1591,8 +1592,8 @@ NSString * const GSSOCKSRecvAddr = @"GSSOCKSRecvAddr"; if (result < 0) { [NSException raise: NSFileHandleOperationException - format: @"failed to move to offset in file - %s", - GSLastErrorStr(errno)]; + format: @"failed to move to offset in file - %@", + [NSError _last]]; } } @@ -1927,8 +1928,8 @@ NSString * const GSSOCKSRecvAddr = @"GSSOCKSRecvAddr"; { NSString *s; - s = [NSString stringWithFormat: @"Accept attempt failed - %s", - GSLastErrorStr(errno)]; + s = [NSString stringWithFormat: @"Accept attempt failed - %@", + [NSError _last]]; [readInfo setObject: s forKey: GSFileHandleNotificationError]; } else @@ -1995,8 +1996,8 @@ NSString * const GSSOCKSRecvAddr = @"GSSOCKSRecvAddr"; { NSString *s; - s = [NSString stringWithFormat: @"Read attempt failed - %s", - GSLastErrorStr(errno)]; + s = [NSString stringWithFormat: @"Read attempt failed - %@", + [NSError _last]]; [readInfo setObject: s forKey: GSFileHandleNotificationError]; [self postReadNotification]; } @@ -2023,16 +2024,26 @@ NSString * const GSSOCKSRecvAddr = @"GSSOCKSRecvAddr"; if (operation == GSFileHandleConnectCompletionNotification || operation == GSSOCKSConnect) { // Connection attempt completed. + extern int errno; int result; + int rval; unsigned len = sizeof(result); - if (getsockopt(descriptor, SOL_SOCKET, SO_ERROR, - (char*)&result, &len) == 0 && result != 0) + rval = getsockopt(descriptor, SOL_SOCKET, SO_ERROR, (char*)&result, &len); + if (rval != 0) { NSString *s; - s = [NSString stringWithFormat: @"Connect attempt failed - %s", - GSLastErrorStr(result)]; + s = [NSString stringWithFormat: @"Connect attempt failed - %@", + [NSError _last]]; + [info setObject: s forKey: GSFileHandleNotificationError]; + } + else if (result != 0) + { + NSString *s; + + s = [NSString stringWithFormat: @"Connect attempt failed - %@", + [NSError _systemError: result]]; [info setObject: s forKey: GSFileHandleNotificationError]; } else @@ -2065,7 +2076,7 @@ NSString * const GSSOCKSRecvAddr = @"GSSOCKSRecvAddr"; NSString *s; s = [NSString stringWithFormat: - @"Write attempt failed - %s", GSLastErrorStr(errno)]; + @"Write attempt failed - %@", [NSError _last]]; [info setObject: s forKey: GSFileHandleNotificationError]; [self postWriteNotification]; } @@ -2141,8 +2152,8 @@ NSString * const GSSOCKSRecvAddr = @"GSSOCKSRecvAddr"; } if (fcntl(descriptor, F_SETFL, e) < 0) { - NSLog(@"unable to set non-blocking mode for %d - %s", - descriptor, GSLastErrorStr(errno)); + NSLog(@"unable to set non-blocking mode for %d - %@", + descriptor, [NSError _last]); } else { @@ -2151,8 +2162,8 @@ NSString * const GSSOCKSRecvAddr = @"GSSOCKSRecvAddr"; } else { - NSLog(@"unable to get non-blocking mode for %d - %s", - descriptor, GSLastErrorStr(errno)); + NSLog(@"unable to get non-blocking mode for %d - %@", + descriptor, [NSError _last]); } } } @@ -2170,11 +2181,11 @@ NSString * const GSSOCKSRecvAddr = @"GSSOCKSRecvAddr"; if (getsockname(descriptor, (struct sockaddr*)&sin, &size) == -1) { - NSLog(@"unable to get socket name - %s", GSLastErrorStr(errno)); + NSLog(@"unable to get socket name - %@", [NSError _last]); } else { - str = [NSString stringWithCString: (char*)inet_ntoa(sin.sin_addr)]; + str = [NSString stringWithUTF8String: (char*)inet_ntoa(sin.sin_addr)]; } return str; } @@ -2187,7 +2198,7 @@ NSString * const GSSOCKSRecvAddr = @"GSSOCKSRecvAddr"; if (getsockname(descriptor, (struct sockaddr*)&sin, &size) == -1) { - NSLog(@"unable to get socket name - %s", GSLastErrorStr(errno)); + NSLog(@"unable to get socket name - %@", [NSError _last]); } else { diff --git a/Source/GSFormat.h b/Source/GSFormat.h deleted file mode 100644 index 1c7b54f8e..000000000 --- a/Source/GSFormat.h +++ /dev/null @@ -1,37 +0,0 @@ -/* GSFormat - printf-style formatting - - Copyright (C) 2000 Free Software Foundation, Inc. - - Written by: Kai Henningsen - Created: Jan 2001 - - 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., 51 Franklin Street, Fifth Floor, Boston, MA 02111 USA. -*/ - -#ifndef __GSFormat_H_ -#define __GSFormat_H_ - -#include -#include "GSPrivate.h" - -@class NSDictionary; - -void -GSFormat(GSStr fb, const unichar *fmt, va_list ap, NSDictionary *loc); - -#endif - diff --git a/Source/GSFormat.m b/Source/GSFormat.m index fb0ab5693..4a28ff8c8 100644 --- a/Source/GSFormat.m +++ b/Source/GSFormat.m @@ -73,7 +73,8 @@ #include "Foundation/NSZone.h" #include "Foundation/NSDebug.h" #include "GNUstepBase/GSLocale.h" -#include "GSFormat.h" + +#include "GSPrivate.h" #include // for strstr() #include @@ -218,10 +219,10 @@ enum /* Digits. */ /* Lower-case digits. */ -const char _itowa_lower_digits[36] +static const char _itowa_lower_digits[36] = "0123456789abcdefghijklmnopqrstuvwxyz"; /* Upper-case digits. */ -const char _itowa_upper_digits[36] +static const char _itowa_upper_digits[36] = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"; @@ -758,9 +759,13 @@ parse_one_spec (const unichar *format, size_t posn, struct printf_spec *spec, return nargs; } +static inline void GSStrAppendUnichar(GSStr s, unichar u) +{ + GSPrivateStrAppendUnichars(s, &u, 1); +} #define outchar(Ch) GSStrAppendUnichar(s, Ch) -#define outstring(String, Len) GSStrAppendUnichars(s, String, Len) +#define outstring(String, Len) GSPrivateStrAppendUnichars(s, String, Len) /* For handling long_double and longlong we use the same flag. If `long' and `long long' are effectively the same type define it to @@ -798,7 +803,7 @@ static unichar *group_number (unichar *, unichar *, const char *, NSString *); /* The function itself. */ void -GSFormat (GSStr s, const unichar *format, va_list ap, +GSPrivateFormat (GSStr s, const unichar *format, va_list ap, NSDictionary *locale) { /* The character used as thousands separator. */ @@ -1690,9 +1695,10 @@ NSDictionary *locale) LABEL (form_strerror): /* Print description of error ERRNO. */ - string = - (unichar *) GSLastErrorStr(save_errno); - is_long = 0; /* This is no wide-char string. */ + errno = save_errno; + string = (unichar *)[[[NSError _last] localizedDescription] + cStringUsingEncoding: NSUnicodeStringEncoding]; + is_long = 1; /* This is a unicode string. */ goto LABEL (print_string); LABEL (form_character): /* Character. */ @@ -1735,7 +1741,7 @@ NSDictionary *locale) { /* Write "(null)" if there's space. */ if (prec == -1 - || prec >= (int) (sizeof (null) / sizeof (null[0])) - 1) + || prec >= (int) (sizeof (null) / sizeof (null[0])) - 1) { string = (unichar *) null; len = (sizeof (null) / sizeof (null[0])) - 1; @@ -1757,8 +1763,8 @@ NSDictionary *locale) if (enc == GSUndefinedEncoding) { - enc = GetDefEncoding(); - byteEncoding = GSIsByteEncoding(enc); + enc = [NSString defaultCStringEncoding]; + byteEncoding = GSPrivateIsByteEncoding(enc); } len = strlen(str); // Number of bytes to convert. diff --git a/Source/GSHTTPURLHandle.m b/Source/GSHTTPURLHandle.m index d0fd2909f..fce29d1f7 100644 --- a/Source/GSHTTPURLHandle.m +++ b/Source/GSHTTPURLHandle.m @@ -617,6 +617,7 @@ static void debugWrite(GSHTTPURLHandle *handle, NSData *data) GSMimeHeader *info; NSString *val; float ver; + int code; connectionState = idle; [nc removeObserver: self name: nil object: sock]; @@ -635,7 +636,8 @@ static void debugWrite(GSHTTPURLHandle *handle, NSData *data) */ info = [document headerNamed: @"http"]; val = [info objectForKey: NSHTTPPropertyStatusCodeKey]; - if ([val intValue] == 401 && self->challenged < 2) + code = [val intValue]; + if (code == 401 && self->challenged < 2) { GSMimeHeader *ah; @@ -734,8 +736,17 @@ static void debugWrite(GSHTTPURLHandle *handle, NSData *data) bodyPos = 0; DESTROY(wData); NSResetMapTable(wProperties); - [self didLoadBytes: [d subdataWithRange: r] - loadComplete: YES]; + if (code >= 200 && code < 300) + { + [self didLoadBytes: [d subdataWithRange: r] + loadComplete: YES]; + } + else + { + [self didLoadBytes: [d subdataWithRange: r] + loadComplete: NO]; + [self cancelLoadInBackground]; + } } else { @@ -1378,8 +1389,8 @@ static void debugWrite(GSHTTPURLHandle *handle, NSData *data) * Tell superclass that the load failed - let it do housekeeping. */ [self backgroundLoadDidFailWithReason: - [NSString stringWithFormat: @"Unable to connect to %@:%@ ... %s", - host, port, GSLastErrorStr(errno)]]; + [NSString stringWithFormat: @"Unable to connect to %@:%@ ... %@", + host, port, [NSError _last]]]; return; } RETAIN(sock); @@ -1389,7 +1400,11 @@ static void debugWrite(GSHTTPURLHandle *handle, NSData *data) name: GSFileHandleConnectCompletionNotification object: sock]; connectionState = connecting; - if (debug) NSLog(@"%@ start connect", NSStringFromSelector(_cmd)); + if (debug) + { + NSLog(@"%@ start connect to %@:%@", + NSStringFromSelector(_cmd), host, port); + } } else { diff --git a/Source/GSLocale.m b/Source/GSLocale.m index 013496cf2..7f5d0ca17 100644 --- a/Source/GSLocale.m +++ b/Source/GSLocale.m @@ -19,7 +19,8 @@ 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., 51 Franklin Street, Fifth Floor, Boston, MA 02111 USA. + Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02111 USA. */ #include "config.h" #include "GNUstepBase/GSLocale.h" @@ -36,6 +37,8 @@ #include "Foundation/NSUserDefaults.h" #include "Foundation/NSBundle.h" +#include "GSPrivate.h" + /* * Function called by [NSObject +initialize] to setup locale information * from environment variables. Must *not* use any ObjC code since it needs @@ -75,12 +78,14 @@ GSSetLocale(int category, NSString *locale) locale = nil; if (clocale != 0) { - locale = [NSString stringWithCString: clocale]; + locale = [NSString stringWithUTF8String: clocale]; } return locale; } -#define GSLanginfo(value) [NSString stringWithCString: nl_langinfo (value)] +#define GSLanginfo(value) [NSString stringWithCString: nl_langinfo (value) \ +encoding: GSPrivateNativeCStringEncoding()] + /* Creates a locale dictionary from information provided by i18n functions. Many, but not all, of the keys are filled in or inferred from the @@ -154,33 +159,33 @@ GSDomainFromDefaultLocale(void) /* Currency Information */ if (lconv->currency_symbol) { - [dict setObject: [NSString stringWithCString: lconv->currency_symbol] + [dict setObject: [NSString stringWithUTF8String: lconv->currency_symbol] forKey: NSCurrencySymbol]; } if (lconv->int_curr_symbol) { - [dict setObject: [NSString stringWithCString: lconv->int_curr_symbol] + [dict setObject: [NSString stringWithUTF8String: lconv->int_curr_symbol] forKey: NSInternationalCurrencyString]; } if (lconv->mon_decimal_point) { - [dict setObject: [NSString stringWithCString: lconv->mon_decimal_point] + [dict setObject: [NSString stringWithUTF8String: lconv->mon_decimal_point] forKey: NSInternationalCurrencyString]; } if (lconv->mon_thousands_sep) { - [dict setObject: [NSString stringWithCString: lconv->mon_thousands_sep] + [dict setObject: [NSString stringWithUTF8String: lconv->mon_thousands_sep] forKey: NSInternationalCurrencyString]; } if (lconv->decimal_point) { - [dict setObject: [NSString stringWithCString: lconv->decimal_point] + [dict setObject: [NSString stringWithUTF8String: lconv->decimal_point] forKey: NSDecimalSeparator]; } if (lconv->thousands_sep) { - [dict setObject: [NSString stringWithCString: lconv->thousands_sep] + [dict setObject: [NSString stringWithUTF8String: lconv->thousands_sep] forKey: NSThousandsSeparator]; } diff --git a/Source/GSPrivate.h b/Source/GSPrivate.h index 9c28e5381..e01802f86 100644 --- a/Source/GSPrivate.h +++ b/Source/GSPrivate.h @@ -21,8 +21,18 @@ MA 02111 USA. */ -#ifndef __GSPrivate_h_ -#define __GSPrivate_h_ +#ifndef _GSPrivate_h_ +#define _GSPrivate_h_ + +#include "Foundation/NSError.h" + +@class NSNotification; + +#if ( (__GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 3) ) && HAVE_VISIBILITY_ATTRIBUTE ) +#define GS_ATTRIB_PRIVATE __attribute__ ((visibility("internal"))) +#else +#define GS_ATTRIB_PRIVATE +#endif /* Absolute Gregorian date for NSDate reference date Jan 01 2001 * @@ -39,6 +49,39 @@ #include "GNUstepBase/GSObjCRuntime.h" +#include "Foundation/NSArray.h" + + +@interface GSArray : NSArray +{ +@public + id *_contents_array; + unsigned _count; +} +@end + +@interface GSMutableArray : NSMutableArray +{ +@public + id *_contents_array; + unsigned _count; + unsigned _capacity; + int _grow_factor; +} +@end + +@interface GSInlineArray : GSArray +{ +} +@end + +@interface GSPlaceholderArray : NSArray +{ +} +@end + +#include "Foundation/NSString.h" + /** * Macro to manage memory for chunks of code that need to work with * arrays of items. Use this to start the block of code using @@ -100,17 +143,6 @@ because NXConstantString returns a pointer to it's internal pointer. */ -/* - * Function to get the name of a string encoding as an NSString. - */ -GS_EXPORT NSString *GSEncodingName(NSStringEncoding encoding); - -/* - * Function to determine whether data in a particular encoding can - * generally be represented as 8-bit characters including ascii. - */ -GS_EXPORT BOOL GSIsByteEncoding(NSStringEncoding encoding); - /* * Type to hold either UTF-16 (unichar) or 8-bit encodings, * while satisfying alignment constraints. @@ -172,11 +204,6 @@ typedef struct { } GSStr_t; typedef GSStr_t *GSStr; -/* - * Functions to append to GSStr - */ -extern void GSStrAppendUnichar(GSStr s, unichar); -extern void GSStrAppendUnichars(GSStr s, const unichar *u, unsigned l); /* * Enumeration for MacOS-X compatibility user defaults settings. @@ -192,21 +219,6 @@ typedef enum { GSUserDefaultMaxFlag // End marker. } GSUserDefaultFlagType; -/* - * Get the dictionary representation. - */ -NSDictionary *GSUserDefaultsDictionaryRepresentation(void); - -/* - * Get one of several potentially useful flags. - */ -BOOL GSUserDefaultsFlag(GSUserDefaultFlagType type); - -/** - * Get a flag from an environment variable - return def if not defined. - */ -BOOL GSEnvironmentFlag(const char *name, BOOL def); - /** @@ -230,13 +242,213 @@ BOOL GSEnvironmentFlag(const char *name, BOOL def); - (const char*) type; @end -/* - * Functions used by the NSRunLoop and friends for processing - * queued notifications. +/* Get error information. */ -extern void GSNotifyASAP(void); -extern void GSNotifyIdle(void); -extern BOOL GSNotifyMore(void); +@interface NSError (GSCategories) ++ (NSError*) _last; ++ (NSError*) _systemError: (long)number; +@end -#endif /* __GSPrivate_h_ */ +/* Used by NSException uncaught exception handler - must not call any + * methods/functions which might cause a recursive exception. + */ +const char* +GSPrivateArgZero() GS_ATTRIB_PRIVATE; + +/* get the available string encodings (nul terminated array) + */ +NSStringEncoding * +GSPrivateAvailableEncodings() GS_ATTRIB_PRIVATE; + +/* Initialise constant strings + */ +void +GSPrivateBuildStrings(void) GS_ATTRIB_PRIVATE; + +/* Used to check for termination of background tasks. + */ +BOOL +GSPrivateCheckTasks(void) GS_ATTRIB_PRIVATE; + +/* get the default C-string encoding. + */ +NSStringEncoding +GSPrivateDefaultCStringEncoding() GS_ATTRIB_PRIVATE; + +/* Get default locale quickly (usually from cache). + * External apps would cache the locale themselves. + */ +NSDictionary * +GSPrivateDefaultLocale() GS_ATTRIB_PRIVATE; + +/* Get one of several standard values. + */ +BOOL +GSPrivateDefaultsFlag(GSUserDefaultFlagType type) GS_ATTRIB_PRIVATE; + +/* get the name of a string encoding as an NSString. + */ +NSString * +GSPrivateEncodingName(NSStringEncoding encoding) GS_ATTRIB_PRIVATE; + +/* get a flag from an environment variable - return def if not defined. + */ +BOOL +GSPrivateEnvironmentFlag(const char *name, BOOL def) GS_ATTRIB_PRIVATE; + +/* Get the path to the xcurrent executable. + */ +NSString * +GSPrivateExecutablePath(void) GS_ATTRIB_PRIVATE; + +/* Format arguments into an internal string. + */ +void +GSPrivateFormat(GSStr fb, const unichar *fmt, va_list ap, NSDictionary *loc) + GS_ATTRIB_PRIVATE; + +/* determine whether data in a particular encoding can + * generally be represented as 8-bit characters including ascii. + */ +BOOL +GSPrivateIsByteEncoding(NSStringEncoding encoding) GS_ATTRIB_PRIVATE; + +/* determine whether encoding is currently supported. + */ +BOOL +GSPrivateIsEncodingSupported(NSStringEncoding encoding) GS_ATTRIB_PRIVATE; + +/* Hash function to hash up to limit bytes from data of specified length. + * If the flag is NO then a result of 0 is mapped to 0xffffffff. + * This is a pretty useful general purpose hash function. + */ +static inline unsigned +GSPrivateHash(const void *data, unsigned length, unsigned limit, BOOL zero) + __attribute__((unused)); +static inline unsigned +GSPrivateHash(const void *data, unsigned length, unsigned limit, BOOL zero) +{ + unsigned ret = length; + unsigned l = length; + + if (limit < length) + { + l = limit; + } + while (l-- > 0) + { + ret = (ret << 5) + ret + ((const unsigned char*)data)[l]; + } + if (ret == 0 && zero == NO) + { + ret = 0xffffffff; + } + return ret; +} + +/* load a module into the runtime + */ +long +GSPrivateLoadModule(NSString *filename, FILE *errorStream, + void (*loadCallback)(Class, struct objc_category *), + void **header, NSString *debugFilename) GS_ATTRIB_PRIVATE; + +/* Get the native C-string encoding as used by locale specific code in the + * operating system. This may differ from the default C-string encoding + * if the latter has bewen set via an environment variable. + */ +NSStringEncoding +GSPrivateNativeCStringEncoding() GS_ATTRIB_PRIVATE; + +/* Function used by the NSRunLoop and friends for processing + * queued notifications which should be processed at the first safe moment. + */ +void GSPrivateNotifyASAP(void) GS_ATTRIB_PRIVATE; + +/* Function used by the NSRunLoop and friends for processing + * queued notifications which should be processed when the loop is idle. + */ +void GSPrivateNotifyIdle(void) GS_ATTRIB_PRIVATE; + +/* Function used by the NSRunLoop and friends for determining whether + * there are more queued notifications to be processed. + */ +BOOL GSPrivateNotifyMore(void) GS_ATTRIB_PRIVATE; + +/* Function to return the hash value for a small integer (used by NSNumber). + */ +unsigned +GSPrivateSmallHash(int n) GS_ATTRIB_PRIVATE; + +/* Function to append data to an GSStr + */ +void +GSPrivateStrAppendUnichars(GSStr s, const unichar *u, unsigned l) + GS_ATTRIB_PRIVATE; + +/* Make the content of this string into unicode if it is not in + * the external defaults C string encoding. + */ +void +GSPrivateStrExternalize(GSStr s) GS_ATTRIB_PRIVATE; + +/* + * GSPrivateSymbolPath() returns the path to the object file from + * which a certain class was loaded. + * + * If the class was loaded from a shared library, this returns the + * filesystem path to the shared library; if it was loaded from a + * dynamical object (such as a bundle or framework dynamically + * loaded), it returns the filesystem path to the object file; if the + * class was loaded from the main executable, it returns the + * filesystem path to the main executable path. + * + * This function is implemented by using the available features of + * the dynamic linker on the specific platform we are running on. + * + * On some platforms, the dynamic linker does not provide enough + * facilities to support the GSPrivateSymbolPath() function at all; + * in this case, GSPrivateSymbolPath() always returns nil. + * + * On my platform (a Debian GNU Linux), it seems the dynamic linker + * always returns the filesystem path that was used to load the + * module. So it returns the full filesystem path for shared libraries + * and bundles (which is very nice), but unfortunately it returns + * argv[0] (which might be something as horrible as './obj/test') + * for classes in the main executable. + * + * If theCategory argument is not NULL, GSPrivateSymbolPath() will return + * the filesystem path to the module from which the category theCategory + * of the class theClass was loaded. + * + * Currently, the function will return nil if any of the following + * conditions is satisfied: + * - the required functionality is not available on the platform we are + * running on; + * - memory allocation fails; + * - the symbol for that class/category could not be found. + * + * In general, if the function returns nil, it means something serious + * went wrong in the system preventing it from getting the symbol path. + * If your code is to be portable, you (unfortunately) have to be prepared + * to work around it in some way when this happens. + * + * It seems that this function has no corresponding function in the NeXT + * runtime ... as far as I know. + */ +NSString * +GSPrivateSymbolPath (Class theClass, Category *theCategory) GS_ATTRIB_PRIVATE; + +/* Combining class for composite unichars + */ +unsigned char +GSPrivateUniCop(unichar u) GS_ATTRIB_PRIVATE; + +/* unload a module from the runtime (not implemented) + */ +long +GSPrivateUnloadModule(FILE *errorStream, + void (*unloadCallback)(Class, struct objc_category *)) GS_ATTRIB_PRIVATE; + +#endif /* _GSPrivate_h_ */ diff --git a/Source/GSSet.m b/Source/GSSet.m index f4978142c..f9034fcf7 100644 --- a/Source/GSSet.m +++ b/Source/GSSet.m @@ -19,7 +19,8 @@ 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., 51 Franklin Street, Fifth Floor, Boston, MA 02111 USA. + Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02111 USA. */ #include "config.h" diff --git a/Source/GSStream.m b/Source/GSStream.m index cf84fec00..8c1184f72 100644 --- a/Source/GSStream.m +++ b/Source/GSStream.m @@ -28,12 +28,12 @@ #include #include #include -#include #include #include #include #include "GSStream.h" +#include "GSPrivate.h" NSString * const NSStreamDataWrittenToMemoryStreamKey = @"NSStreamDataWrittenToMemoryStreamKey"; @@ -228,10 +228,7 @@ static RunLoopEventType typeForStream(NSStream *aStream) { if ([_modes containsObject: mode]) { - if ([self _isOpened]) - { - [_runloop removeStream: self mode: mode]; - } + [_runloop removeStream: self mode: mode]; [_modes removeObject: mode]; if ([_modes count] == 0) { @@ -251,6 +248,10 @@ static RunLoopEventType typeForStream(NSStream *aStream) mode = [mode copy]; [_modes addObject: mode]; RELEASE(mode); + /* We only add open streams to the runloop .. subclasses may add + * streams when they are in the process of opening if they need + * to do so. + */ if ([self _isOpened]) { [_runloop addStream: self mode: mode]; @@ -364,7 +365,7 @@ static RunLoopEventType typeForStream(NSStream *aStream) theError = [NSError errorWithDomain: NSPOSIXErrorDomain code: errno userInfo: nil]; - NSLog(@"%@ error(%d): - %s", self, errno, GSLastErrorStr(errno)); + NSLog(@"%@ error(%d): - %@", self, errno, [NSError _last]); ASSIGN(_lastError, theError); _currentStatus = NSStreamStatusError; } @@ -1216,7 +1217,7 @@ static NSString * const GSSOCKSAckConn = @"GSSOCKSAckConn"; a = [NSString stringWithUTF8String: (const char*)rbuffer]; } - else if (rbuffer[3] == 4) + else { unsigned char buf[40]; int i = 4; diff --git a/Source/GSString.m b/Source/GSString.m index 7eda9e196..1afb07543 100644 --- a/Source/GSString.m +++ b/Source/GSString.m @@ -48,17 +48,19 @@ #include "Foundation/NSObjCRuntime.h" #include "Foundation/NSKeyedArchiver.h" #include "GNUstepBase/GSObjCRuntime.h" -#include "GSFormat.h" #include #include "GSPrivate.h" -extern BOOL GSEncodingSupported(NSStringEncoding enc); - /* memcpy(), strlen(), strcmp() are gcc builtin's */ #include "GNUstepBase/Unicode.h" +static BOOL isByteEncoding(NSStringEncoding enc) +{ + return GSPrivateIsByteEncoding(enc); +} + #ifdef NeXT_RUNTIME /* Used by the Darwin/NeXT ObjC Runtime until Apple Radar 2870817 is fixed. */ @@ -250,10 +252,18 @@ setup(void) if (beenHere == NO) { - extern NSStringEncoding GetDefEncoding(void); - beenHere = YES; + /* + * Cache the default string encoding, and set the internal encoding + * used by 8-bit character strings to match if possible. + */ + externalEncoding = GSPrivateDefaultCStringEncoding(); + if (isByteEncoding(externalEncoding) == YES) + { + internalEncoding = externalEncoding; + } + /* * Cache pointers to classes to work round misfeature in * GNU compiler/runtime system where class lookup is very slow. @@ -291,16 +301,6 @@ setup(void) caiSel = @selector(characterAtIndex:); gcrSel = @selector(getCharacters:range:); ranSel = @selector(rangeOfComposedCharacterSequenceAtIndex:); - - /* - * Cache the default string encoding, and set the internal encoding - * used by 8-bit character strings to match if possible. - */ - externalEncoding = GetDefEncoding(); - if (GSIsByteEncoding(externalEncoding) == YES) - { - internalEncoding = externalEncoding; - } } } @@ -451,7 +451,7 @@ fixBOM(unsigned char **bytes, unsigned *length, BOOL *shouldFree, void *chars = 0; BOOL flag = NO; - if (GSEncodingSupported(encoding) == NO) + if (GSPrivateIsEncodingSupported(encoding) == NO) { return nil; // Invalid encoding } @@ -494,7 +494,7 @@ fixBOM(unsigned char **bytes, unsigned *length, BOOL *shouldFree, BOOL isLatin1 = NO; GSStr me; - if (GSEncodingSupported(encoding) == NO) + if (GSPrivateIsEncodingSupported(encoding) == NO) { if (flag == YES && bytes != 0) { @@ -536,7 +536,7 @@ fixBOM(unsigned char **bytes, unsigned *length, BOOL *shouldFree, encoding = internalEncoding; } } - else if (encoding != internalEncoding && GSIsByteEncoding(encoding) == YES) + else if (encoding != internalEncoding && isByteEncoding(encoding) == YES) { unsigned i; @@ -704,7 +704,7 @@ fixBOM(unsigned char **bytes, unsigned *length, BOOL *shouldFree, /* * Now set up 'f' as a GSMutableString object whose initial buffer is - * allocated on the stack. The GSFormat function can write into it. + * allocated on the stack. The GSPrivateFormat function can write into it. */ f.isa = GSMutableStringClass; f._zone = NSDefaultMallocZone(); @@ -713,7 +713,7 @@ fixBOM(unsigned char **bytes, unsigned *length, BOOL *shouldFree, f._count = 0; f._flags.wide = 0; f._flags.free = 0; - GSFormat(&f, fmt, argList, locale); + GSPrivateFormat(&f, fmt, argList, locale); if (fmt != fbuf) { objc_free(fmt); @@ -1026,7 +1026,7 @@ canBeConvertedToEncoding_c(GSStr self, NSStringEncoding enc) && enc != internalEncoding && enc != NSUTF8StringEncoding && enc != NSUnicodeStringEncoding - && ((internalEncoding != NSASCIIStringEncoding) || !GSIsByteEncoding(enc))) + && ((internalEncoding != NSASCIIStringEncoding) || !isByteEncoding(enc))) { unsigned l = 0; unichar *r = 0; @@ -1404,7 +1404,7 @@ dataUsingEncoding_c(GSStr self, NSStringEncoding encoding, BOOL lossy) if ((encoding == internalEncoding) || ((internalEncoding == NSASCIIStringEncoding) - && (encoding == NSUTF8StringEncoding || GSIsByteEncoding(encoding)))) + && (encoding == NSUTF8StringEncoding || isByteEncoding(encoding)))) { unsigned char *buff; @@ -1624,7 +1624,10 @@ getCString_c(GSStr self, char *buffer, unsigned int maxLength, o._contents.c = self->_contents.c; GSStrWiden((GSStr)&o); getCString_u((GSStr)&o, buffer, maxLength, aRange, leftoverRange); - NSZoneFree(o._zone, o._contents.u); + if (o._flags.free == 1) + { + NSZoneFree(o._zone, o._contents.u); + } return; } @@ -1788,7 +1791,7 @@ getCStringE_c(GSStr self, char *buffer, unsigned int maxLength, } if (enc == NSUTF8StringEncoding - && GSIsByteEncoding(internalEncoding)) + && isByteEncoding(internalEncoding)) { unsigned i; @@ -1823,7 +1826,7 @@ getCStringE_c(GSStr self, char *buffer, unsigned int maxLength, } if (enc == NSASCIIStringEncoding - && GSIsByteEncoding(internalEncoding)) + && isByteEncoding(internalEncoding)) { unsigned i; @@ -3447,8 +3450,9 @@ agree, create a new GSUnicodeInlineString otherwise. /* * Make sure we have the format string in a nul terminated array of - * unichars for passing to GSFormat. Use on-stack memory for performance - * unless the size of the format string is really big (a rare occurrence). + * unichars for passing to GSPrivateFormat. Use on-stack memory for + * performance unless the size of the format string is really big + * (a rare occurrence). */ len = [format length]; if (len >= 1024) @@ -3470,7 +3474,7 @@ agree, create a new GSUnicodeInlineString otherwise. _zone = GSObjCZone(self); #endif } - GSFormat((GSStr)self, fmt, ap, nil); + GSPrivateFormat((GSStr)self, fmt, ap, nil); _flags.hash = 0; // Invalidate the hash for this string. if (fmt != buf) { @@ -3778,7 +3782,7 @@ NSAssert(_flags.free == 1 && _zone != 0, NSInternalInconsistencyException); encoding = internalEncoding; } } - else if (encoding != internalEncoding && GSIsByteEncoding(encoding) == YES) + else if (encoding != internalEncoding && isByteEncoding(encoding) == YES) { unsigned i; @@ -3968,7 +3972,7 @@ NSAssert(_flags.free == 1 && _zone != 0, NSInternalInconsistencyException); [format getCharacters: fmt]; fmt[len] = '\0'; - GSFormat((GSStr)self, fmt, argList, locale); + GSPrivateFormat((GSStr)self, fmt, argList, locale); if (fmt != fbuf) { objc_free(fmt); @@ -5025,7 +5029,8 @@ NSAssert(_flags.free == 1 && _zone != 0, NSInternalInconsistencyException); /** * Append characters to a string. */ -void GSStrAppendUnichars(GSStr s, const unichar *u, unsigned l) +void +GSPrivateStrAppendUnichars(GSStr s, const unichar *u, unsigned l) { /* * Make the string wide if necessary. @@ -5097,45 +5102,9 @@ void GSStrAppendUnichars(GSStr s, const unichar *u, unsigned l) } } -void GSStrAppendUnichar(GSStr s, unichar u) -{ - /* - * Make the string wide if necessary. - */ - if (s->_flags.wide == 0) - { - if (u > 255 || (u > 127 && internalEncoding != NSISOLatin1StringEncoding)) - { - GSStrWiden(s); - } - } - /* - * Make room for the characters we are appending. - */ - if (s->_count + 2 >= s->_capacity) - { - GSStrMakeSpace(s, 1); - } - - /* - * Copy the characters into place. - */ - if (s->_flags.wide == 1) - { - s->_contents.u[s->_count++] = u; - } - else - { - s->_contents.c[s->_count++] = u; - } -} - -/* - * Make the content of this string into unicode if it is not in - * the external defaults C string encoding. - */ -void GSStrExternalize(GSStr s) +void +GSPrivateStrExternalize(GSStr s) { if (s->_flags.wide == 0 && internalEncoding != externalEncoding) { diff --git a/Source/GSURLPrivate.h b/Source/GSURLPrivate.h index ff2f22e43..6ab7ea57d 100644 --- a/Source/GSURLPrivate.h +++ b/Source/GSURLPrivate.h @@ -33,7 +33,6 @@ #include "Foundation/NSAutoreleasePool.h" #include "Foundation/NSData.h" #include "Foundation/NSDictionary.h" -#include "Foundation/NSError.h" #include "Foundation/NSException.h" #include "Foundation/NSHTTPCookie.h" #include "Foundation/NSHTTPCookieStorage.h" diff --git a/Source/GSValue.m b/Source/GSValue.m index 421714ced..225319dba 100644 --- a/Source/GSValue.m +++ b/Source/GSValue.m @@ -18,7 +18,8 @@ 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., 51 Franklin Street, Fifth Floor, Boston, MA 02111 USA. + Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02111 USA. */ #include "config.h" diff --git a/Source/GSeq.h b/Source/GSeq.h index f925a9820..9e9f6ddc0 100644 --- a/Source/GSeq.h +++ b/Source/GSeq.h @@ -167,9 +167,10 @@ static inline void GSeq_normalize(GSeq seq) notdone = NO; for (i = 1; i < count; i++) { - if (uni_cop(*second)) + if (GSPrivateUniCop(*second)) { - if (uni_cop(*first) > uni_cop(*second)) + if (GSPrivateUniCop(*first) + > GSPrivateUniCop(*second)) { unichar tmp = *first; @@ -177,7 +178,8 @@ static inline void GSeq_normalize(GSeq seq) *second = tmp; notdone = YES; } - else if (uni_cop(*first) == uni_cop(*second)) + else if (GSPrivateUniCop(*first) + == GSPrivateUniCop(*second)) { if (*first > *second) { diff --git a/Source/Makefile.postamble b/Source/Makefile.postamble index f15373c53..647431c0b 100644 --- a/Source/Makefile.postamble +++ b/Source/Makefile.postamble @@ -54,12 +54,9 @@ after-install:: $(INSTALL_DATA) ../Headers/Additions/GNUstepBase/$$file \ $(GNUSTEP_HEADERS)/GNUstepBase/$$file ; \ done - for file in $(UNICODE_HEADERS); do \ - $(INSTALL_DATA) ../Headers/Additions/GNUstepBase/$$file \ - $(GNUSTEP_HEADERS)/GNUstepBase/$$file ; \ - done - $(INSTALL_DATA) $(GNUSTEP_TARGET_DIR)/GSConfig.h \ - $(GNUSTEP_HEADERS)/$(GNUSTEP_TARGET_DIR) + $(MKDIRS) $(GNUSTEP_HEADERS)/$(GNUSTEP_TARGET_DIR)/GNUstepBase + $(INSTALL_DATA) $(GNUSTEP_TARGET_DIR)/GNUstepBase/GSConfig.h \ + $(GNUSTEP_HEADERS)/$(GNUSTEP_TARGET_DIR)/GNUstepBase/GSConfig.h if [ "$(INSTALL_ROOT_DIR)" = "" ]; then \ services=/etc/services; \ if [ "`$(WHOAMI)`" != root ]; then \ @@ -84,10 +81,7 @@ before-uninstall:: for file in $(GNU_HEADERS); do \ rm -f $(GNUSTEP_HEADERS)/GNUstepBase/$$file ; \ done - for file in $(UNICODE_HEADERS); do \ - rm -f $(GNUSTEP_HEADERS)/GNUstepBase/$$file ; \ - done - rm -f $(GNUSTEP_HEADERS)/$(GNUSTEP_TARGET_DIR)/GSConfig.h + rm -f $(GNUSTEP_HEADERS)/$(GNUSTEP_TARGET_DIR)/GNUstepBase/GSConfig.h # Things to do before cleaning # before-clean:: @@ -103,9 +97,9 @@ after-clean:: after-distclean:: rm -f mframe/mframe.h Foundation \ NSNumber[0-9]*.m GSValue[0-9]*.m - rm -rf $(GNUSTEP_TARGET_DIR)/config.h + rm -rf $(GNUSTEP_TARGET_DIR)/GNUstepBase + rm -rf $(GNUSTEP_TARGET_DIR)/mframe.h rm -rf $(GNUSTEP_TARGET_DIR)/mframe.h - rm -rf $(GNUSTEP_TARGET_DIR)/GSConfig.h rm -rf $(GNUSTEP_TARGET_CPU) # Things to do before checking @@ -130,10 +124,10 @@ $(GNUSTEP_TARGET_DIR)/config.h: ../config.status -mv $(HEADER_DIR_BASE)/config.h $(GNUSTEP_TARGET_DIR) -touch $(GNUSTEP_TARGET_DIR)/config.h -$(GNUSTEP_TARGET_DIR)/GSConfig.h: ../config.status - $(MKDIRS) $(GNUSTEP_TARGET_DIR) - -mv $(HEADER_DIR_BASE)/GSConfig.h $(GNUSTEP_TARGET_DIR) - -touch $(GNUSTEP_TARGET_DIR)/GSConfig.h +$(GNUSTEP_TARGET_DIR)/GNUstepBase/GSConfig.h: ../config.status + $(MKDIRS) $(GNUSTEP_TARGET_DIR)/GNUstepBase + -mv $(HEADER_DIR_BASE)/GSConfig.h $(GNUSTEP_TARGET_DIR)/GNUstepBase + -touch $(GNUSTEP_TARGET_DIR)/GNUstepBase/GSConfig.h $(GNUSTEP_TARGET_DIR)/mframe.h: mframe/config.status $(MKDIRS) $(GNUSTEP_TARGET_DIR) diff --git a/Source/Makefile.preamble b/Source/Makefile.preamble index 2733671ca..cf4ce45e5 100644 --- a/Source/Makefile.preamble +++ b/Source/Makefile.preamble @@ -62,8 +62,10 @@ ADDITIONAL_OBJCFLAGS = ADDITIONAL_CFLAGS = # Additional include directories the compiler should search -ADDITIONAL_INCLUDE_DIRS = -I../Headers/Additions -I../Headers \ - -I./$(GNUSTEP_TARGET_DIR) +ADDITIONAL_INCLUDE_DIRS = \ + -I../Headers/Additions \ + -I../Headers \ + -I./$(GNUSTEP_TARGET_DIR) # Additional LDFLAGS to pass to the linker ADDITIONAL_LDFLAGS = diff --git a/Source/NSAffineTransform.m b/Source/NSAffineTransform.m new file mode 100644 index 000000000..0f3a0c281 --- /dev/null +++ b/Source/NSAffineTransform.m @@ -0,0 +1,600 @@ +/** NSAffineTransform.m + + + This class provides a way to perform affine transforms. It provides + a matrix for transforming from one coordinate system to another. + + Copyright (C) 1996,1999 Free Software Foundation, Inc. + + Author: Ovidiu Predescu + Date: August 1997 + Author: Richard Frith-Macdonald + Date: March 1999 + + 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., 51 Franklin Street, Fifth Floor, + Boston, MA 02111 USA. +*/ + +#include "config.h" +#include + +#import "Foundation/NSArray.h" +#import "Foundation/NSException.h" +#import "Foundation/NSString.h" +#import "Foundation/NSAffineTransform.h" +#import "Foundation/NSCoder.h" +#import "Foundation/NSDebug.h" + +/* Private definitions */ +#define A _matrix.m11 +#define B _matrix.m12 +#define C _matrix.m21 +#define D _matrix.m22 +#define TX _matrix.tX +#define TY _matrix.tY + +/* A Postscript matrix looks like this: + + / a b 0 \ + | c d 0 | + \ tx ty 1 / + + */ + +static const float pi = 3.1415926535897932384626434; + +#if 0 +#define valid(o) NSAssert((o->_isIdentity && o->A==1.0 && o->B==0.0 && o->C==0.0 && o->D==1.0) || (o->_isFlipY && o->A==1.0 && o->B==0.0 && o->C==0.0 && o->D==-1.0) || !(o->_isIdentity||o->_isFlipY), NSInternalInconsistencyException) +#define check() valid(self) +#else +#define valid(o) +#define check() +#endif + +/* Quick function to multiply two coordinate matrices. C = AB */ +static inline NSAffineTransformStruct +matrix_multiply (NSAffineTransformStruct MA, NSAffineTransformStruct MB) +{ + NSAffineTransformStruct MC; + MC.m11 = MA.m11 * MB.m11 + MA.m12 * MB.m21; + MC.m12 = MA.m11 * MB.m12 + MA.m12 * MB.m22; + MC.m21 = MA.m21 * MB.m11 + MA.m22 * MB.m21; + MC.m22 = MA.m21 * MB.m12 + MA.m22 * MB.m22; + MC.tX = MA.tX * MB.m11 + MA.tY * MB.m21 + MB.tX; + MC.tY = MA.tX * MB.m12 + MA.tY * MB.m22 + MB.tY; + return MC; +} + +/* + MC.m11 = MA->A * MB->A + MA->B * MB->C; + MC.m12 = MA->A * MB->B + MA->B * MB->D; + MC.m21 = MA->C * MB->A + MA->D * MB->C; + MC.m22 = MA->C * MB->B + MA->D * MB->D; + MC.tX = MA->TX * MB->A + MA->TY * MB->C + MB->TX; + MC.tY = MA->TX * MB->B + MA->TY * MB->D + MB->TY; + */ + +@implementation NSAffineTransform + +static NSAffineTransformStruct identityTransform = { + 1.0, 0.0, 0.0, 1.0, 0.0, 0.0 +}; + +/** + * Return an autoreleased instance of this class. + */ ++ (NSAffineTransform*) transform +{ + NSAffineTransform *t; + + t = (NSAffineTransform*)NSAllocateObject(self, 0, NSDefaultMallocZone()); + t->_matrix = identityTransform; + t->_isIdentity = YES; + return AUTORELEASE(t); +} + +/** + * Return an autoreleased instance of this class. + */ ++ (id) new +{ + NSAffineTransform *t; + + t = (NSAffineTransform*)NSAllocateObject(self, 0, NSDefaultMallocZone()); + t->_matrix = identityTransform; + t->_isIdentity = YES; + return t; +} + +/** + * Appends the transform matrix to the receiver. This is done by performing a + * matrix multiplication of the receiver with aTransform so that aTransform + * is the first transform applied to the user coordinate. The new + * matrix then replaces the receiver's matrix. + */ +- (void) appendTransform: (NSAffineTransform*)aTransform +{ + valid(aTransform); + + if (aTransform->_isIdentity) + { + TX += aTransform->TX; + TY += aTransform->TY; + check(); + return; + } + + if (aTransform->_isFlipY) + { + B = -B; + D = -D; + TX = aTransform->TX + TX; + TY = aTransform->TY - TY; + if (_isIdentity) + { + _isFlipY = YES; + _isIdentity = NO; + } + else if (_isFlipY) + { + _isFlipY = NO; + _isIdentity = YES; + } + check(); + return; + } + + if (_isIdentity) + { + A = aTransform->A; + B = aTransform->B; + C = aTransform->C; + D = aTransform->D; + TX = TX * aTransform->A + TY * aTransform->C + aTransform->TX; + TY = TX * aTransform->B + TY * aTransform->D + aTransform->TY; + _isIdentity = NO; // because aTransform is not an identity transform. + _isFlipY = aTransform->_isFlipY; + check(); + return; + } + + if (_isFlipY) + { + A = aTransform->A; + B = aTransform->B; + C = -aTransform->C; + D = -aTransform->D; + TX = TX * aTransform->A + TY * aTransform->C + aTransform->TX; + TY = TX * aTransform->B + TY * aTransform->D + aTransform->TY; + _isIdentity = NO; + _isFlipY = NO; + check(); + return; + } + + _matrix = matrix_multiply(_matrix, aTransform->_matrix); + _isIdentity = NO; + _isFlipY = NO; + check(); +} + +- (NSString*) description +{ + return [NSString stringWithFormat: + @"NSAffineTransform ((%f, %f) (%f, %f) (%f, %f))", A, B, C, D, TX, TY]; +} + +/** + * Initialize the transformation matrix instance to the identity matrix. + * The identity matrix transforms a point to itself. + */ +- (id) init +{ + _matrix = identityTransform; + _isIdentity = YES; + return self; +} + +/** + * Initialize the receiever's instance with the instance represented + * by aTransform. + */ +- (id) initWithTransform: (NSAffineTransform*)aTransform +{ + _matrix = aTransform->_matrix; + _isIdentity = aTransform->_isIdentity; + _isFlipY = aTransform->_isFlipY; + return self; +} + +/** + * Calculates the inverse of the receiver's matrix and replaces the + * receiever's matrix with it. + */ +- (void) invert +{ + float newA, newB, newC, newD, newTX, newTY; + float det; + + if (_isIdentity) + { + TX = -TX; + TY = -TY; + return; + } + + if (_isFlipY) + { + TX = -TX; + return; + } + + det = A * D - B * C; + if (det == 0) + { + NSLog (@"error: determinant of matrix is 0!"); + return; + } + + newA = D / det; + newB = -B / det; + newC = -C / det; + newD = A / det; + newTX = (-D * TX + C * TY) / det; + newTY = (B * TX - A * TY) / det; + + NSDebugLLog(@"NSAffineTransform", + @"inverse of matrix ((%f, %f) (%f, %f) (%f, %f))\n" + @"is ((%f, %f) (%f, %f) (%f, %f))", + A, B, C, D, TX, TY, + newA, newB, newC, newD, newTX, newTY); + + A = newA; B = newB; + C = newC; D = newD; + TX = newTX; TY = newTY; +} + +/** + * Prepends the transform matrix to the receiver. This is done by performing a + * matrix multiplication of the receiver with aTransform so that aTransform + * is the last transform applied to the user coordinate. The new + * matrix then replaces the receiver's matrix. + */ +- (void) prependTransform: (NSAffineTransform*)aTransform +{ + valid(aTransform); + + if (aTransform->_isIdentity) + { + TX = aTransform->TX * A + aTransform->TY * C + TX; + TY = aTransform->TX * B + aTransform->TY * D + TY; + check(); + return; + } + + if (aTransform->_isFlipY) + { + TX = aTransform->TX * A + aTransform->TY * C + TX; + TY = aTransform->TX * B + aTransform->TY * D + TY; + C = -C; + D = -D; + if (_isIdentity) + { + _isFlipY = YES; + _isIdentity = NO; + } + else if (_isFlipY) + { + _isFlipY = NO; + _isIdentity = YES; + } + check(); + return; + } + + if (_isIdentity) + { + A = aTransform->A; + B = aTransform->B; + C = aTransform->C; + D = aTransform->D; + TX += aTransform->TX; + TY += aTransform->TY; + _isIdentity = NO; + _isFlipY = aTransform->_isFlipY; + check(); + return; + } + + if (_isFlipY) + { + A = aTransform->A; + B = -aTransform->B; + C = aTransform->C; + D = -aTransform->D; + TX += aTransform->TX; + TY -= aTransform->TY; + _isIdentity = NO; + _isFlipY = NO; + check(); + return; + } + + _matrix = matrix_multiply(aTransform->_matrix, _matrix); + _isIdentity = NO; + _isFlipY = NO; + check(); +} + +/** + * Applies the rotation specified by angle in degrees. Points transformed + * with the transformation matrix of the receiver are rotated counter-clockwise + * by the number of degrees specified by angle. + */ +- (void) rotateByDegrees: (float)angle +{ + [self rotateByRadians: pi * angle / 180]; +} + +/** + * Applies the rotation specified by angle in radians. Points transformed + * with the transformation matrix of the receiver are rotated counter-clockwise + * by the number of radians specified by angle. + */ +- (void) rotateByRadians: (float)angleRad +{ + if (angleRad != 0.0) + { + float sine; + float cosine; + NSAffineTransformStruct rotm; + + sine = sin (angleRad); + cosine = cos (angleRad); + rotm.m11 = cosine; + rotm.m12 = sine; + rotm.m21 = -sine; + rotm.m22 = cosine; + rotm.tX = rotm.tY = 0; + _matrix = matrix_multiply(rotm, _matrix); + _isIdentity = NO; + _isFlipY = NO; + check(); + } +} + +/** + * Scales the transformation matrix of the reciever by the factor specified + * by scale. + */ +- (void) scaleBy: (float)scale +{ + NSAffineTransformStruct scam = identityTransform; + + scam.m11 = scale; + scam.m22 = scale; + _matrix = matrix_multiply(scam, _matrix); + _isIdentity = NO; + _isFlipY = NO; + check(); +} + +/** + * Scales the X axis of the receiver's transformation matrix + * by scaleX and the Y axis of the transformation matrix by scaleY. + */ +- (void) scaleXBy: (float)scaleX yBy: (float)scaleY +{ + if (_isIdentity && scaleX == 1.0) + { + if (scaleY == 1.0) + { + return; // no scaling + } + if (scaleY == -1.0) + { + D = -1.0; + _isFlipY = YES; + _isIdentity = NO; + return; + } + } + + if (_isFlipY && scaleX == 1.0) + { + if (scaleY == 1.0) + { + return; // no scaling + } + if (scaleY == -1.0) + { + D = 1.0; + _isFlipY = NO; + _isIdentity = YES; + return; + } + } + + A *= scaleX; + B *= scaleX; + C *= scaleY; + D *= scaleY; + _isIdentity = NO; + _isFlipY = NO; +} + +/** + *

+ * Sets the structure which represents the matrix of the reciever. + * The struct is of the form:

+ *

{m11, m12, m21, m22, tX, tY}

+ */ +- (void) setTransformStruct: (NSAffineTransformStruct)val +{ + _matrix = val; + _isIdentity = NO; + _isFlipY = NO; + if (A == 1.0 && B == 0.0 && C == 0.0) + { + if (D == 1.0) + { + _isIdentity = YES; + } + else if (D == -1.0) + { + _isFlipY = YES; + } + } + check(); +} + +/** + * Transforms a single point based on the transformation matrix. + * Returns the resulting point. + */ +- (NSPoint) transformPoint: (NSPoint)aPoint +{ + NSPoint new; + + if (_isIdentity) + { + new.x = TX + aPoint.x; + new.y = TY + aPoint.y; + } + else if (_isFlipY) + { + new.x = TX + aPoint.x; + new.y = TY - aPoint.y; + } + else + { + new.x = A * aPoint.x + C * aPoint.y + TX; + new.y = B * aPoint.x + D * aPoint.y + TY; + } + + return new; +} + +/** + * Transforms the NSSize represented by aSize using the reciever's + * transformation matrix. Returns the resulting NSSize.
+ * NB. A transform can result in negative size components ... so calling + * code should check for and deal with that situation. + */ +- (NSSize) transformSize: (NSSize)aSize +{ + if (_isIdentity) + { + return aSize; + } + else + { + NSSize new; + + if (_isFlipY) + { + new.width = aSize.width; + new.height = -aSize.height; + } + else + { + new.width = A * aSize.width + C * aSize.height; + new.height = B * aSize.width + D * aSize.height; + } + return new; + } +} + +/** + *

+ * Returns the NSAffineTransformStruct structure + * which represents the matrix of the reciever. + * The struct is of the form:

+ *

{m11, m12, m21, m22, tX, tY}

+ */ +- (NSAffineTransformStruct) transformStruct +{ + return _matrix; +} + +/** + * Applies the translation specified by tranX and tranY to the receiver's + * matrix. + * Points transformed by the reciever's matrix after this operation will + * be shifted in position based on the specified translation. + */ +- (void) translateXBy: (float)tranX yBy: (float)tranY +{ + if (_isIdentity) + { + TX += tranX; + TY += tranY; + } + else if (_isFlipY) + { + TX += tranX; + TY -= tranY; + } + else + { + TX += A * tranX + C * tranY; + TY += B * tranX + D * tranY; + } + check(); +} + +- (id) copyWithZone: (NSZone*)zone +{ + return NSCopyObject(self, 0, zone); +} + +- (BOOL) isEqual: (id)anObject +{ + if ([anObject class] == isa) + { + NSAffineTransform *o = anObject; + + if (A == o->A && B == o->B && C == o->C + && D == o->D && TX == o->TX && TY == o->TY) + return YES; + } + return NO; +} + +- (id) initWithCoder: (NSCoder*)aCoder +{ + NSAffineTransformStruct replace; + + [aCoder decodeArrayOfObjCType: @encode(float) + count: 6 + at: (float*)&replace]; + [self setTransformStruct: replace]; + return self; +} + +- (void) encodeWithCoder: (NSCoder*)aCoder +{ + NSAffineTransformStruct replace; + + replace = [self transformStruct]; + [aCoder encodeArrayOfObjCType: @encode(float) + count: 6 + at: (float*)&replace]; +} + +@end /* NSAffineTransform */ + diff --git a/Source/NSArchiver.m b/Source/NSArchiver.m index a4fd51e5b..b8d3da645 100644 --- a/Source/NSArchiver.m +++ b/Source/NSArchiver.m @@ -858,7 +858,7 @@ static Class NSMutableDataMallocClass; if (node) { c = (Class)node->value.ptr; - return [NSString stringWithCString: GSNameFromClass(c)]; + return [NSString stringWithUTF8String: GSNameFromClass(c)]; } } return trueName; diff --git a/Source/NSArray.m b/Source/NSArray.m index 3d7c5a58d..d8af47b25 100644 --- a/Source/NSArray.m +++ b/Source/NSArray.m @@ -23,7 +23,8 @@ 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., 51 Franklin Street, Fifth Floor, Boston, MA 02111 USA. + Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02111 USA. NSArray class reference $Date$ $Revision$ @@ -45,12 +46,23 @@ #include "Foundation/NSDebug.h" #include "Foundation/NSValue.h" #include "Foundation/NSNull.h" +#include "Foundation/NSUserDefaults.h" // For private method _decodeArrayOfObjectsForKey: #include "Foundation/NSKeyedArchiver.h" #include "GNUstepBase/GSCategories.h" #include "GSPrivate.h" -extern BOOL GSMacOSXCompatiblePropertyLists(void); +static BOOL GSMacOSXCompatiblePropertyLists(void) +{ +#if defined(HAVE_LIBXML) + if (GSPrivateDefaultsFlag(NSWriteOldStylePropertyLists) == YES) + return NO; + return GSPrivateDefaultsFlag(GSMacOSXCompatible); +#else + return NO; +#endif +} + extern void GSPropertyListMake(id,NSDictionary*,BOOL,BOOL,unsigned,id*); @interface NSArrayEnumerator : NSEnumerator @@ -67,19 +79,6 @@ extern void GSPropertyListMake(id,NSDictionary*,BOOL,BOOL,unsigned,id*); -@class GSArray; -@interface GSArray : NSObject // Help the compiler -@end -@class GSInlineArray; -@interface GSInlineArray : NSObject // Help the compiler -@end -@class GSMutableArray; -@interface GSMutableArray : NSObject // Help the compiler -@end -@class GSPlaceholderArray; -@interface GSPlaceholderArray : NSObject // Help the compiler -@end - static Class NSArrayClass; static Class GSArrayClass; static Class GSInlineArrayClass; @@ -1202,10 +1201,11 @@ compare(id elem1, id elem2, void* context) */ - (BOOL) writeToFile: (NSString *)path atomically: (BOOL)useAuxiliaryFile { - NSDictionary *loc = GSUserDefaultsDictionaryRepresentation(); + NSDictionary *loc; NSString *desc = nil; NSData *data; + loc = [[NSUserDefaults standardUserDefaults] dictionaryRepresentation]; if (GSMacOSXCompatiblePropertyLists() == YES) { GSPropertyListMake(self, loc, YES, NO, 2, &desc); @@ -1228,10 +1228,11 @@ compare(id elem1, id elem2, void* context) */ - (BOOL) writeToURL: (NSURL *)url atomically: (BOOL)useAuxiliaryFile { - NSDictionary *loc = GSUserDefaultsDictionaryRepresentation(); + NSDictionary *loc; NSString *desc = nil; NSData *data; + loc = [[NSUserDefaults standardUserDefaults] dictionaryRepresentation]; if (GSMacOSXCompatiblePropertyLists() == YES) { GSPropertyListMake(self, loc, YES, NO, 2, &desc); diff --git a/Source/NSAssertionHandler.m b/Source/NSAssertionHandler.m index c8d153541..b4c4737a3 100644 --- a/Source/NSAssertionHandler.m +++ b/Source/NSAssertionHandler.m @@ -18,7 +18,8 @@ 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., 51 Franklin Street, Fifth Floor, Boston, MA 02111 USA. + Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02111 USA. NSAssertionHandler class reference $Date$ $Revision$ diff --git a/Source/NSBundle.m b/Source/NSBundle.m index 6a1dd7f34..f8ccab2e3 100644 --- a/Source/NSBundle.m +++ b/Source/NSBundle.m @@ -23,7 +23,8 @@ 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., 51 Franklin Street, Fifth Floor, Boston, MA 02111 USA. + Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02111 USA. NSBundle class reference @@ -50,7 +51,9 @@ #include "Foundation/NSPathUtilities.h" #include "Foundation/NSData.h" #include "Foundation/NSValue.h" -#include "GNUstepBase/GSFunctions.h" + +#include "GSPrivate.h" + #ifdef HAVE_UNISTD_H #include #endif @@ -83,7 +86,7 @@ static NSString *_launchDirectory = nil; */ static NSDictionary *_emptyTable = nil; -/* When we are linking in an object file, objc_load_modules calls our +/* When we are linking in an object file, GSPrivateLoadModule calls our callback routine for every Class and Category loaded. The following variable stores the bundle that is currently doing the loading so we know where to store the class names. @@ -213,7 +216,8 @@ AbsolutePathOfExecutable(NSString *path, BOOL atLaunch) /* * Return the path to this executable. */ -static NSString *ExecutablePath() +NSString * +GSPrivateExecutablePath() { static NSString *executablePath = nil; static BOOL beenHere = NO; @@ -226,7 +230,7 @@ static NSString *ExecutablePath() #ifdef PROCFS_EXE_LINK executablePath = [[NSFileManager defaultManager] pathContentOfSymbolicLinkAtPath: - [NSString stringWithCString: PROCFS_EXE_LINK]]; + [NSString stringWithUTF8String: PROCFS_EXE_LINK]]; /* On some systems, the link is of the form "[device]:inode", which @@ -257,24 +261,6 @@ static NSString *ExecutablePath() return executablePath; } -/* This function is provided for objc-load.c, although I'm not sure it - really needs it (So far only needed if using GNU dld library) */ -#ifdef __MINGW32__ -const unichar * -objc_executable_location (void) -{ - return [[ExecutablePath() stringByDeletingLastPathComponent] - fileSystemRepresentation]; -} -#else -const char * -objc_executable_location (void) -{ - return [[ExecutablePath() stringByDeletingLastPathComponent] - fileSystemRepresentation]; -} -#endif - static BOOL bundle_directory_readable(NSString *path) { @@ -377,13 +363,86 @@ _bundle_name_first_match(NSString* directory, NSString* name) static inline NSString * _find_framework(NSString *name) { - NSArray *paths; + NSArray *paths; + NSFileManager *file_mgr = [NSFileManager defaultManager]; + NSString *file_name = [name stringByAppendingPathExtension:@"framework"]; + NSString *file_path; + NSString *path; + NSEnumerator *enumerator; + NSCParameterAssert(name != nil); + paths = NSSearchPathForDirectoriesInDomains(GSFrameworksDirectory, NSAllDomainsMask,YES); - return GSFindNamedFile(paths, name, @"framework"); + + enumerator = [paths objectEnumerator]; + while ((path = [enumerator nextObject])) + { + file_path = [path stringByAppendingPathComponent: file_name]; + + if ([file_mgr fileExistsAtPath: file_path] == YES) + { + return file_path; // Found it! + } + } + return nil; } + +/* Try to locate resources for tool name (which is this tool) in + * standard places like xxx/Library/Tools/Resources/name */ +/* This could be converted into a public +bundleForTool: + * method. At the moment it's only used privately + * to locate the main bundle for this tool. + */ +static inline NSString * +_find_main_bundle_for_tool(NSString *toolName) +{ + NSArray *paths; + NSEnumerator *enumerator; + NSString *path; + NSString *tail; + NSFileManager *fm = [NSFileManager defaultManager]; + + /* + * Eliminate any base path or extensions. + */ + toolName = [toolName lastPathComponent]; + do + { + toolName = [toolName stringByDeletingPathExtension]; + } + while ([[toolName pathExtension] length] > 0); + + if ([toolName length] == 0) + { + return nil; + } + + tail = [@"Tools" stringByAppendingPathComponent: + [@"Resources" stringByAppendingPathComponent: + toolName]]; + + paths = NSSearchPathForDirectoriesInDomains (NSLibraryDirectory, + NSAllDomainsMask, YES); + + enumerator = [paths objectEnumerator]; + while ((path = [enumerator nextObject])) + { + BOOL isDir; + path = [path stringByAppendingPathComponent: tail]; + + if ([fm fileExistsAtPath: path isDirectory: &isDir] && isDir) + { + return path; + } + } + + return nil; +} + + + @interface NSBundle (Private) + (NSString *) _absolutePathOfExecutable: (NSString *)path; + (void) _addFrameworkFromClass: (Class)frameworkClass; @@ -464,8 +523,9 @@ _find_framework(NSString *name) && !strncmp ("NSFramework_", frameworkClass->name, 12)) { /* The name of the framework. */ - NSString *name = [NSString stringWithCString: &frameworkClass->name[12]]; + NSString *name; + name = [NSString stringWithUTF8String: &frameworkClass->name[12]]; /* Important - gnustep-make mangles framework names to encode * them as ObjC class names. Here we need to demangle them. We * apply the reverse transformations in the reverse order. @@ -479,9 +539,9 @@ _find_framework(NSString *name) * really universal way of getting the framework path ... we can * locate the framework no matter where it is on disk! */ - bundlePath = objc_get_symbol_path (frameworkClass, NULL); + bundlePath = GSPrivateSymbolPath (frameworkClass, NULL); - if ([bundlePath isEqualToString: ExecutablePath()]) + if ([bundlePath isEqualToString: GSPrivateExecutablePath()]) { /* Ops ... the NSFramework_xxx class is linked in the main * executable. Maybe the framework was statically linked @@ -565,8 +625,8 @@ _find_framework(NSString *name) if (bundlePath == nil) { /* NICOLA: In an ideal world, the following is just a hack - * for when objc_get_symbol_path() fails! But in real life - * objc_get_symbol_path() is risky (some platforms don't + * for when GSPrivateSymbolPath() fails! But in real life + * GSPrivateSymbolPath() is risky (some platforms don't * have it at all!), so this hack might be used a lot! It * must be quite robust. We try to look for the framework * in the standard GNUstep installation dirs and in the main @@ -669,7 +729,7 @@ typedef struct { @defs(NSBundle) } *bptr; -void +static void _bundle_load_callback(Class theClass, struct objc_category *theCategory) { NSCAssert(_loadingBundle, NSInternalInconsistencyException); @@ -714,85 +774,91 @@ _bundle_load_callback(Class theClass, struct objc_category *theCategory) if (self == [NSBundle class]) { NSDictionary *env; + NSString *str; _emptyTable = RETAIN([NSDictionary dictionary]); - /* Need to make this recursive since both mainBundle and initWithPath: - want to lock the thread */ + /* Need to make this recursive since both mainBundle and + * initWithPath: want to lock the thread. + */ load_lock = [NSRecursiveLock new]; env = [[NSProcessInfo processInfo] environment]; - if (env) - { - NSString *str; - - if ((str = [env objectForKey: @"GNUSTEP_TARGET_CPU"]) != nil) - gnustep_target_cpu = RETAIN(str); - else if ((str = [env objectForKey: @"GNUSTEP_HOST_CPU"]) != nil) - gnustep_target_cpu = RETAIN(str); - - if ((str = [env objectForKey: @"GNUSTEP_TARGET_OS"]) != nil) - gnustep_target_os = RETAIN(str); - else if ((str = [env objectForKey: @"GNUSTEP_HOST_OS"]) != nil) - gnustep_target_os = RETAIN(str); - - if ((str = [env objectForKey: @"GNUSTEP_TARGET_DIR"]) != nil) - gnustep_target_dir = RETAIN(str); - else if ((str = [env objectForKey: @"GNUSTEP_HOST_DIR"]) != nil) - gnustep_target_dir = RETAIN(str); - - if ((str = [env objectForKey: @"LIBRARY_COMBO"]) != nil) - library_combo = RETAIN(str); - - _launchDirectory = RETAIN([[NSFileManager defaultManager] - currentDirectoryPath]); - - _gnustep_bundle = RETAIN([self bundleForLibrary: @"gnustep-base"]); + /* These variables are used when we are running non-flattened. + * This means that there are multiple binaries for different + * OSes, and we need constantly to choose the right one (eg, + * when loading a bundle or a framework). The choice is based + * on these environments variables that are set by GNUstep.sh + * (you must source GNUstep.sh when non-flattened). + */ + if ((str = [env objectForKey: @"GNUSTEP_TARGET_CPU"]) != nil) + gnustep_target_cpu = RETAIN(str); + else if ((str = [env objectForKey: @"GNUSTEP_HOST_CPU"]) != nil) + gnustep_target_cpu = RETAIN(str); + + if ((str = [env objectForKey: @"GNUSTEP_TARGET_OS"]) != nil) + gnustep_target_os = RETAIN(str); + else if ((str = [env objectForKey: @"GNUSTEP_HOST_OS"]) != nil) + gnustep_target_os = RETAIN(str); + + if ((str = [env objectForKey: @"GNUSTEP_TARGET_DIR"]) != nil) + gnustep_target_dir = RETAIN(str); + else if ((str = [env objectForKey: @"GNUSTEP_HOST_DIR"]) != nil) + gnustep_target_dir = RETAIN(str); + + if ((str = [env objectForKey: @"LIBRARY_COMBO"]) != nil) + library_combo = RETAIN(str); + + _launchDirectory = RETAIN([[NSFileManager defaultManager] + currentDirectoryPath]); + + _gnustep_bundle = RETAIN([self bundleForLibrary: @"gnustep-base" + version: OBJC_STRINGIFY(GNUSTEP_BASE_MAJOR_VERSION.GNUSTEP_BASE_MINOR_VERSION)]); + #if 0 - _loadingBundle = [self mainBundle]; - handle = objc_open_main_module(stderr); - printf("%08x\n", handle); + _loadingBundle = [self mainBundle]; + handle = objc_open_main_module(stderr); + printf("%08x\n", handle); #endif #if NeXT_RUNTIME + { + int i, numClasses = 0, newNumClasses = objc_getClassList(NULL, 0); + Class *classes = NULL; + while (numClasses < newNumClasses) { + numClasses = newNumClasses; + classes = objc_realloc(classes, sizeof(Class) * numClasses); + newNumClasses = objc_getClassList(classes, numClasses); + } + for (i = 0; i < numClasses; i++) { - int i, numClasses = 0, newNumClasses = objc_getClassList(NULL, 0); - Class *classes = NULL; - while (numClasses < newNumClasses) { - numClasses = newNumClasses; - classes = objc_realloc(classes, sizeof(Class) * numClasses); - newNumClasses = objc_getClassList(classes, numClasses); - } - for (i = 0; i < numClasses; i++) - { - [self _addFrameworkFromClass: classes[i]]; - } - objc_free(classes); + [self _addFrameworkFromClass: classes[i]]; } + objc_free(classes); + } #else + { + void *state = NULL; + Class class; + + while ((class = objc_next_class(&state))) { - void *state = NULL; - Class class; - - while ((class = objc_next_class(&state))) + unsigned int len = strlen (class->name); + + if (len > sizeof("NSFramework_") + && !strncmp("NSFramework_", class->name, 12)) { - unsigned int len = strlen (class->name); - - if (len > sizeof("NSFramework_") - && !strncmp("NSFramework_", class->name, 12)) - { - [self _addFrameworkFromClass: class]; - } + [self _addFrameworkFromClass: class]; } } + } #endif #if 0 - // _bundle_load_callback(class, NULL); - // bundle = (NSBundle *)NSMapGet(_bundles, bundlePath); - - objc_close_main_module(handle); - _loadingBundle = nil; + // _bundle_load_callback(class, NULL); + // bundle = (NSBundle *)NSMapGet(_bundles, bundlePath); + + objc_close_main_module(handle); + _loadingBundle = nil; #endif - } } } @@ -873,7 +939,7 @@ _bundle_load_callback(Class theClass, struct objc_category *theCategory) * and the main bundle directory is xxx/Tools/Resources/Control. *

*

(when the tool has not yet been installed, it's similar - - * xxx/shared_obj/ix86/linux-gnu/gnu-gnu-gnu/Control + * xxx/obj/ix86/linux-gnu/gnu-gnu-gnu/Control * and the main bundle directory is xxx/Resources/Control). *

*

(For a flattened structure, the structure is the same without the @@ -892,17 +958,23 @@ _bundle_load_callback(Class theClass, struct objc_category *theCategory) /* We don't know at the beginning if it's a tool or an application. */ BOOL isApplication = YES; + /* Sometimes we detect that this is a non-installed tool. That is + * special because we want to lookup local resources before installed + * ones. Keep track of this special case in this variable. + */ + BOOL isNonInstalledTool = NO; + /* If it's a tool, we will need the tool name. Since we don't know yet if it's a tool or an application, we always store the executable name here - just in case it turns out it's a tool. */ - NSString *toolName = [ExecutablePath() lastPathComponent]; -#if defined(__WIN32__) + NSString *toolName = [GSPrivateExecutablePath() lastPathComponent]; +#if defined(__WIN32__) || defined(__CYGWIN__) toolName = [toolName stringByDeletingPathExtension]; #endif /* Strip off the name of the program */ - path = [ExecutablePath() stringByDeletingLastPathComponent]; + path = [GSPrivateExecutablePath() stringByDeletingLastPathComponent]; /* We now need to chop off the extra subdirectories, the library combo and the target cpu/os if they exist. The executable @@ -928,12 +1000,13 @@ _bundle_load_callback(Class theClass, struct objc_category *theCategory) } /* object dir */ s = [path lastPathComponent]; - if ([s hasSuffix: @"_obj"]) + if ([s hasSuffix: @"obj"]) { path = [path stringByDeletingLastPathComponent]; /* if it has an object dir it can only be a non-yet-installed tool. */ isApplication = NO; + isNonInstalledTool = YES; } if (isApplication == YES) @@ -953,8 +1026,52 @@ _bundle_load_callback(Class theClass, struct objc_category *theCategory) if (isApplication == NO) { - path = [path stringByAppendingPathComponent: @"Resources"]; - path = [path stringByAppendingPathComponent: toolName]; + NSString *maybePath = nil; + + if (isNonInstalledTool) + { + /* We're pretty confident about this case. 'path' is + * obtained by {tool location on disk} and walking up + * until we got out of the obj directory. So we're + * now in GNUSTEP_BUILD_DIR. Resources will be in + * Resources/{toolName}. + */ + path = [path stringByAppendingPathComponent: @"Resources"]; + maybePath = [path stringByAppendingPathComponent: toolName]; + + /* PS: We could check here if we found the resources, + * and if not, keep going with the other attempts at + * locating them. But if we know that this is an + * uninstalled tool, really we don't want to use + * installed resources - we prefer resource lookup to + * fail so the developer will fix whatever issue they + * have with their building. + */ + } + else + { + if (maybePath == nil) + { + /* This is for gnustep-make version 2, where tool resources + * are in GNUSTEP_*_LIBRARY/Tools/Resources/{toolName}. + */ + maybePath = _find_main_bundle_for_tool (toolName); + } + + /* If that didn't work, maybe the tool was created with + * gnustep-make version 1. So we try {tool location on + * disk after walking up the non-flattened + * dirs}/Resources/{toolName}, which is where + * gnustep-make version 1 would put resources. + */ + if (maybePath == nil) + { + path = [path stringByAppendingPathComponent: @"Resources"]; + maybePath = [path stringByAppendingPathComponent: toolName]; + } + } + + path = maybePath; } NSDebugMLLog(@"NSBundle", @"Found main in %@\n", path); @@ -984,6 +1101,14 @@ _bundle_load_callback(Class theClass, struct objc_category *theCategory) if (!aClass) return nil; + /* This is asked relatively frequently inside gnustep-base itself; + * shortcut it. + */ + if (aClass == [NSObject class]) + { + return _gnustep_bundle; + } + [load_lock lock]; bundle = nil; enumerate = NSEnumerateMapTable(_bundles); @@ -1016,19 +1141,23 @@ _bundle_load_callback(Class theClass, struct objc_category *theCategory) /* * Take the path to the binary containing the class and - * convert it to the format for a library name as used - * for obtaining a library resource bundle. + * convert it to the format for a library name as used for + * obtaining a library resource bundle. */ - lib = objc_get_symbol_path (aClass, NULL); - if ([lib isEqual: ExecutablePath()] == YES) + lib = GSPrivateSymbolPath (aClass, NULL); + if ([lib isEqual: GSPrivateExecutablePath()] == YES) { lib = nil; // In program, not library. } /* - * Get the library bundle ... if there wasn't one - * then we will assume the class was in the program - * executable and return the mainBundle instead. + * Get the library bundle ... if there wasn't one then we + * will assume the class was in the program executable and + * return the mainBundle instead. + * + * FIXME: This will not work well with versioned library + * resources. It used to work fine (maybe) with unversioned + * library resources. */ bundle = [NSBundle bundleForLibrary: lib]; if (bundle == nil) @@ -1037,9 +1166,9 @@ _bundle_load_callback(Class theClass, struct objc_category *theCategory) } /* - * Add the class to the list of classes known to be in - * the library or executable. We didn't find it there - * to start with, so we know it's safe to add now. + * Add the class to the list of classes known to be in the + * library or executable. We didn't find it there to start + * with, so we know it's safe to add now. */ if (bundle->_bundleClasses == nil) { @@ -1354,8 +1483,7 @@ _bundle_load_callback(Class theClass, struct objc_category *theCategory) _codeLoaded before loading the bundle. */ _codeLoaded = YES; - if (objc_load_module([object fileSystemRepresentation], - stderr, _bundle_load_callback, NULL, NULL)) + if (GSPrivateLoadModule(object, stderr, _bundle_load_callback, 0, 0)) { _codeLoaded = NO; DESTROY(_loadingFrameworks); @@ -1406,6 +1534,19 @@ _bundle_load_callback(Class theClass, struct objc_category *theCategory) return YES; } +- (void) release +{ + /* We lock during release so that other threads can't grab the + * object between us checking the reference count and deallocating. + */ + [load_lock lock]; + if (NSDecrementExtraRefCountWasZero(self)) + { + [self dealloc]; + } + [load_lock unlock]; +} + /* This method is the backbone of the resource searching for NSBundle. It constructs an array of paths, where each path is a possible location for a resource in the bundle. The current algorithm for searching goes: @@ -1562,7 +1703,7 @@ _bundle_load_callback(Class theClass, struct objc_category *theCategory) } + (NSArray*) _pathsForResourcesOfType: (NSString*)extension - inRootDirectory: (NSString*)bundlePath + inRootDirectory: (NSString*)bundlePath inSubDirectory: (NSString *)subPath { BOOL allfiles; @@ -1622,18 +1763,21 @@ _bundle_load_callback(Class theClass, struct objc_category *theCategory) inDirectory: subPath]; enumerator = [paths objectEnumerator]; - while( (path = [enumerator nextObject]) ) + while ((path = [enumerator nextObject]) != nil) { /* Add all non-localized paths, plus ones in the particular localization (if there is one). */ NSString *theDir = [path stringByDeletingLastPathComponent]; - if ([[theDir pathExtension] isEqual: @"lproj"] == NO - || (localizationName != nil - && [localizationName length] != 0 - && [[theDir lastPathComponent] hasPrefix: localizationName]) ) - { + + if ([[theDir pathExtension] isEqual: @"lproj"] == NO) + { [result addObject: path]; } + else if ([localizationName length] > 0 + && [[theDir lastPathComponent] hasPrefix: localizationName]) + { + [result insertObject: path atIndex: 0]; + } } return result; @@ -1644,8 +1788,34 @@ _bundle_load_callback(Class theClass, struct objc_category *theCategory) inDirectory: (NSString*)subPath forLocalization: (NSString*)localizationName { - [self notImplemented: _cmd]; - return nil; + CREATE_AUTORELEASE_POOL(arp); + NSString *result = nil; + NSArray *array; + + array = [self pathsForResourcesOfType: ext + inDirectory: subPath + forLocalization: localizationName]; + + if (array != nil) + { + NSEnumerator *enumerator = [array objectEnumerator]; + NSString *path; + + name = [name stringByAppendingPathExtension: ext]; + while ((path = [enumerator nextObject]) != nil) + { + NSString *found = [path lastPathComponent]; + + if ([found isEqualToString: name] == YES) + { + result = path; + break; // localised paths occur before non-localised + } + } + } + RETAIN(result); + DESTROY(arp); + return AUTORELEASE(result); } + (NSArray *) preferredLocalizationsFromArray: (NSArray *)localizationsArray @@ -1674,7 +1844,7 @@ _bundle_load_callback(Class theClass, struct objc_category *theCategory) return [array makeImmutableCopyOnFail: NO]; } -- (NSDictionary *)localizedInfoDictionary +- (NSDictionary*) localizedInfoDictionary { NSString *path; NSArray *locales; @@ -1887,11 +2057,11 @@ _bundle_load_callback(Class theClass, struct objc_category *theCategory) } if (self == _mainBundle) { - return ExecutablePath(); + return GSPrivateExecutablePath(); } if (self->_bundleType == NSBUNDLE_LIBRARY) { - return objc_get_symbol_path ([self principalClass], NULL); + return GSPrivateSymbolPath ([self principalClass], NULL); } object = [[self infoDictionary] objectForKey: @"NSExecutable"]; if (object == nil || [object length] == 0) @@ -2023,37 +2193,21 @@ _bundle_load_callback(Class theClass, struct objc_category *theCategory) @implementation NSBundle (GNUstep) -/** - *

Return a bundle which accesses the first existing directory from the list - * GNUSTEP_USER_ROOT/Libraries/Resources/libraryName/ - * GNUSTEP_NETWORK_ROOT/Libraries/Resources/libraryName/ - * GNUSTEP_LOCAL_ROOT/Libraries/Resources/libraryName/ - * GNUSTEP_SYSTEM_ROOT/Libraries/Resources/libraryName/
- * Where libraryName is the name of a library without the lib - * prefix or any extensions. - *

- *

This method exists to provide resource bundles for libraries and hos no - * particular relationship to the library code itsself. The named library - * could be a dynamic library linked in to the running program, a static - * library (whose code may not even exist on the host machine except where - * it is linked in to the program), or even a library which is not linked - * into the program at all (eg. where you want to share resources provided - * for a library you do not actually use). - *

- *

The bundle for the library gnustep-base is a special case ... - * for this bundle the -principalClass method returns [NSObject] and the - * -executablePath method returns the path to the gnustep-base dynamic - * library (if it can be found). As a general rule, library bundles are - * not guaranteed to return values for these methods as the library may - * not exist on disk. - *

- */ + (NSBundle *) bundleForLibrary: (NSString *)libraryName { + return [self bundleForLibrary: libraryName version: nil]; +} + ++ (NSBundle *) bundleForLibrary: (NSString *)libraryName + version: (NSString *)interfaceVersion +{ + /* Important: if you change this code, make sure to also + * change NSUserDefault's manual gnustep-base resource + * lookup to match. + */ NSArray *paths; NSEnumerator *enumerator; NSString *path; - NSString *tail; NSFileManager *fm = [NSFileManager defaultManager]; /* @@ -2072,40 +2226,106 @@ _bundle_load_callback(Class theClass, struct objc_category *theCategory) { libraryName = [libraryName substringFromIndex: 3]; } - /* - * Discard debug/profile library suffix - */ - if ([libraryName hasSuffix: @"_d"] == YES - || [libraryName hasSuffix: @"_p"] == YES) - { - libraryName = [libraryName substringToIndex: [libraryName length] - 3]; - } if ([libraryName length] == 0) { return nil; } - tail = [@"Resources" stringByAppendingPathComponent: libraryName]; - - paths = NSSearchPathForDirectoriesInDomains (GSLibrariesDirectory, + /* + * We expect to find the library resources into: + * + * GNUSTEP_LIBRARY/Libraries//Versions//Resources/ + * + * if no is specified, and if can't find any versioned + * resources in those directories, we'll also accept the old unversioned format + * + * GNUSTEP_LIBRARY/Libraries/Resources// + * + */ + paths = NSSearchPathForDirectoriesInDomains (NSLibraryDirectory, NSAllDomainsMask, YES); - + enumerator = [paths objectEnumerator]; - while ((path = [enumerator nextObject])) + while ((path = [enumerator nextObject]) != nil) { + NSBundle *b; BOOL isDir; - path = [path stringByAppendingPathComponent: tail]; + path = [path stringByAppendingPathComponent: @"Libraries"]; if ([fm fileExistsAtPath: path isDirectory: &isDir] && isDir) { - NSBundle *b = [self bundleWithPath: path]; - - if (b != nil && b->_bundleType == NSBUNDLE_BUNDLE) + if (interfaceVersion != nil) { - b->_bundleType = NSBUNDLE_LIBRARY; + /* We're looking for a specific version. */ + path = [[[[path stringByAppendingPathComponent: libraryName] + stringByAppendingPathComponent: @"Versions"] + stringByAppendingPathComponent: interfaceVersion] + stringByAppendingPathComponent: @"Resources"]; + if ([fm fileExistsAtPath: path isDirectory: &isDir] && isDir) + { + b = [self bundleWithPath: path]; + + if (b != nil && b->_bundleType == NSBUNDLE_BUNDLE) + { + b->_bundleType = NSBUNDLE_LIBRARY; + } + return b; + } + } + else + { + /* Any version will do. */ + NSString *versionsPath = [[path stringByAppendingPathComponent: libraryName] + stringByAppendingPathComponent: @"Versions"]; + + if ([fm fileExistsAtPath: versionsPath isDirectory: &isDir] && isDir) + { + /* TODO: Ignore subdirectories. */ + NSEnumerator *fileEnumerator = [fm enumeratorAtPath: versionsPath]; + NSString *potentialPath; + + while ((potentialPath = [fileEnumerator nextObject]) != nil) + { + potentialPath = [versionsPath + stringByAppendingPathComponent: + [potentialPath + stringByAppendingPathComponent: @"Resources"]]; + if ([fm fileExistsAtPath: potentialPath isDirectory: &isDir] && isDir) + { + b = [self bundleWithPath: potentialPath]; + + if (b != nil && b->_bundleType == NSBUNDLE_BUNDLE) + { + b->_bundleType = NSBUNDLE_LIBRARY; + } + return b; + } + } + } + + /* We didn't find anything! For backwards + * compatibility, try the unversioned directory itself: + * we used to put library resources directly in + * unversioned directories such as + * GNUSTEP_LIBRARY/Libraries/Resources/gnustep-base/{resources + * here}. This was deprecated/obsoleted on 9 March 2007 + * when we added library resource versioning. + */ + { + NSString *oldResourcesPath = [[path stringByAppendingPathComponent: @"Resources"] + stringByAppendingPathComponent: libraryName]; + if ([fm fileExistsAtPath: oldResourcesPath isDirectory: &isDir] && isDir) + { + b = [self bundleWithPath: oldResourcesPath]; + if (b != nil && b->_bundleType == NSBUNDLE_BUNDLE) + { + b->_bundleType = NSBUNDLE_LIBRARY; + } + return b; + } + } } - return b; } } diff --git a/Source/NSCalendarDate.m b/Source/NSCalendarDate.m index 427df9e67..d2d7021fe 100644 --- a/Source/NSCalendarDate.m +++ b/Source/NSCalendarDate.m @@ -672,7 +672,7 @@ static inline int getDigits(const char *from, char *to, int limit, BOOL *error) sourceLen = strlen(source); if (locale == nil) { - locale = GSUserDefaultsDictionaryRepresentation(); + locale = GSPrivateDefaultLocale(); } if (fmt == nil) { @@ -2266,7 +2266,7 @@ static void Grow(DescriptionInfo *info, unsigned size) DescriptionInfo info; if (locale == nil) - locale = GSUserDefaultsDictionaryRepresentation(); + locale = GSPrivateDefaultLocale(); if (format == nil) format = [locale objectForKey: NSTimeDateFormatString]; diff --git a/Source/NSCallBacks.h b/Source/NSCallBacks.h index caa5eae9a..c99592cdc 100644 --- a/Source/NSCallBacks.h +++ b/Source/NSCallBacks.h @@ -21,7 +21,8 @@ * * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02111 USA. */ + * Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02111 USA. */ #ifndef __NSCallBacks_h_OBJECTS_INCLUDE #define __NSCallBacks_h_OBJECTS_INCLUDE 1 @@ -31,53 +32,63 @@ #include "Foundation/NSObject.h" #include "Foundation/NSString.h" + +#if ( (__GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 3) ) && HAVE_VISIBILITY_ATTRIBUTE ) +#define GS_HIDDEN __attribute__ ((visibility("hidden"))) +#else +#define GS_HIDDEN +#endif + + + /**** Type, Constant, and Macro Definitions **********************************/ /**** Function Prototypes ****************************************************/ /** For `int's **/ -unsigned int _NS_int_hash(void *table, void* i); -BOOL _NS_int_is_equal(void *table, void* i, void* j); -void _NS_int_retain(void *table, void* i); -void _NS_int_release(void *table, void* i); -NSString *_NS_int_describe(void *table, void* i); +unsigned int _NS_int_hash(void *table, void* i) GS_HIDDEN; +BOOL _NS_int_is_equal(void *table, void* i, void* j) GS_HIDDEN; +void _NS_int_retain(void *table, void* i) GS_HIDDEN; +void _NS_int_release(void *table, void* i) GS_HIDDEN; +NSString *_NS_int_describe(void *table, void* i) GS_HIDDEN; /** For owned `void *' **/ -unsigned int _NS_owned_void_p_hash(void *table, void *p); -BOOL _NS_owned_void_p_is_equal(void *table, void *p, void *q); -void _NS_owned_void_p_retain(void *table, void *p); -void _NS_owned_void_p_release(void *table, void *p); -NSString *_NS_owned_void_p_describe(void *table, void *p); +unsigned int _NS_owned_void_p_hash(void *table, void *p) GS_HIDDEN; +BOOL _NS_owned_void_p_is_equal(void *table, void *p, void *q) GS_HIDDEN; +void _NS_owned_void_p_retain(void *table, void *p) GS_HIDDEN; +void _NS_owned_void_p_release(void *table, void *p) GS_HIDDEN; +NSString *_NS_owned_void_p_describe(void *table, void *p) GS_HIDDEN; /** For non-retained Objective-C objects **/ -unsigned int _NS_non_retained_id_hash(void *table, id o); -BOOL _NS_non_retained_id_is_equal(void *table, id o, id p); -void _NS_non_retained_id_retain(void *table, id o); -void _NS_non_retained_id_release(void *table, id o); -NSString *_NS_non_retained_id_describe(void *table, id o); +unsigned int _NS_non_retained_id_hash(void *table, id o) GS_HIDDEN; +BOOL _NS_non_retained_id_is_equal(void *table, + id o, id p) GS_HIDDEN; +void _NS_non_retained_id_retain(void *table, id o) GS_HIDDEN; +void _NS_non_retained_id_release(void *table, id o) GS_HIDDEN; +NSString *_NS_non_retained_id_describe(void *table, id o) GS_HIDDEN; /** For(retainable) objects **/ -unsigned int _NS_id_hash(void *table, id o); -BOOL _NS_id_is_equal(void *table, id o, id p); -void _NS_id_retain(void *table, id o); -void _NS_id_release(void *table, id o); -NSString *_NS_id_describe(void *table, id o); +unsigned int _NS_id_hash(void *table, id o) GS_HIDDEN; +BOOL _NS_id_is_equal(void *table, id o, id p) GS_HIDDEN; +void _NS_id_retain(void *table, id o) GS_HIDDEN; +void _NS_id_release(void *table, id o) GS_HIDDEN; +NSString *_NS_id_describe(void *table, id o) GS_HIDDEN; /** For(non-owned) `void *' **/ -unsigned int _NS_non_owned_void_p_hash(void *table, void *p); -BOOL _NS_non_owned_void_p_is_equal(void *table, void *p, void *q); -void _NS_non_owned_void_p_retain(void *table, void *p); -void _NS_non_owned_void_p_release(void *table, void *p); -NSString *_NS_non_owned_void_p_describe(void *table, void *p); +unsigned int _NS_non_owned_void_p_hash(void *table, void *p) GS_HIDDEN; +BOOL _NS_non_owned_void_p_is_equal(void *table, void *p, void *q) GS_HIDDEN; +void _NS_non_owned_void_p_retain(void *table, void *p) GS_HIDDEN; +void _NS_non_owned_void_p_release(void *table, void *p) GS_HIDDEN; +NSString *_NS_non_owned_void_p_describe(void *table, void *p) GS_HIDDEN; /** For pointers to structures and `int *' **/ -unsigned int _NS_int_p_hash(void *table, int *p); -BOOL _NS_int_p_is_equal(void *table, int *p, int *q); -void _NS_int_p_retain(void *table, int *p); -void _NS_int_p_release(void *table, int *p); -NSString *_NS_int_p_describe(void *table, int *p); +unsigned int _NS_int_p_hash(void *table, int *p) GS_HIDDEN; +BOOL _NS_int_p_is_equal(void *table, int *p, int *q) GS_HIDDEN; +void _NS_int_p_retain(void *table, int *p) GS_HIDDEN; +void _NS_int_p_release(void *table, int *p) GS_HIDDEN; +NSString *_NS_int_p_describe(void *table, int *p) GS_HIDDEN; #endif /* __NSCallBacks_h_OBJECTS_INCLUDE **/ diff --git a/Source/NSCallBacks.m b/Source/NSCallBacks.m index dd8ea6d9e..307240ba9 100644 --- a/Source/NSCallBacks.m +++ b/Source/NSCallBacks.m @@ -24,7 +24,8 @@ NSCallBacks class reference $Date$ $Revision$ - * Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111 USA. */ + * Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02111 USA. */ /**** Included Headers *******************************************************/ diff --git a/Source/NSCharacterSet.m b/Source/NSCharacterSet.m index 4527c8602..868f29f9a 100644 --- a/Source/NSCharacterSet.m +++ b/Source/NSCharacterSet.m @@ -3,6 +3,7 @@ Written by: Adam Fedor Date: Apr 1995 + Updates by: Richard Frith-Macdonald This file is part of the GNUstep Base Library. @@ -33,16 +34,19 @@ #include "Foundation/NSData.h" #include "Foundation/NSLock.h" #include "Foundation/NSDictionary.h" +#include "Foundation/NSIndexSet.h" #include "Foundation/NSThread.h" #include "Foundation/NSNotification.h" #include "Foundation/NSCharacterSet.h" -#include +#include "Foundation/NSData.h" #include "Foundation/NSDebug.h" +//#define GNUSTEP_INDEX_CHARSET 1 +#undef GNUSTEP_INDEX_CHARSET + #include "NSCharacterSetData.h" //PENDING: may want to make these less likely to conflict -#define UNICODE_SIZE 63336 #define UNICODE_MAX 1114112 #define BITMAP_SIZE 8192 #define BITMAP_MAX 139264 @@ -53,10 +57,29 @@ #define ISSET(a,i) ((a) & (1<<(i))) #endif -@class NSDataStatic; +@interface _GSIndexCharSet : NSCharacterSet +{ + NSMutableIndexSet *indexes; +} +- (NSIndexSet*) _indexes; +- (id) initWithBitmap: (NSData*)d; +@end + +@interface _GSMutableIndexCharSet : NSMutableCharacterSet +{ + NSMutableIndexSet *indexes; +} +@end + @interface NSDataStatic : NSObject // Help the compiler @end +/* Private class from NSIndexSet.m + */ +@interface _GSStaticIndexSet : NSIndexSet +- (id) _initWithBytes: (const void*)bytes length: (unsigned)length; +@end + @interface NSBitmapCharSet : NSCharacterSet { const unsigned char *_data; @@ -478,8 +501,47 @@ static NSCharacterSet *cache_set[MAX_STANDARD_SETS]; static NSLock *cache_lock = nil; static Class abstractClass = nil; static Class abstractMutableClass = nil; +static Class concreteClass = nil; +static Class concreteMutableClass = nil; -@interface GSStaticCharSet : NSCharacterSet +#if defined(GNUSTEP_INDEX_CHARSET) +@interface _GSStaticCharSet : _GSIndexCharSet +{ + int _index; +} +@end + +@implementation _GSStaticCharSet + +- (Class) classForCoder +{ + return abstractClass; +} + +- (void) encodeWithCoder: (NSCoder*)aCoder +{ + [aCoder encodeValueOfObjCType: @encode(int) at: &_index]; +} + +- (id) init +{ + DESTROY(self); + return nil; +} + +- (id) initWithBitmap: (NSData*)bitmap number: (int)number +{ + _index = number; + indexes = [[_GSStaticIndexSet alloc] _initWithBytes: [bitmap bytes] + length: [bitmap length]]; + return self; +} + +@end + +#else /* GNUSTEP_INDEX_CHARSET */ + +@interface _GSStaticCharSet : NSCharacterSet { const unsigned char *_data; unsigned _length; @@ -490,7 +552,7 @@ static Class abstractMutableClass = nil; } @end -@implementation GSStaticCharSet +@implementation _GSStaticCharSet + (void) initialize { @@ -499,7 +561,7 @@ static Class abstractMutableClass = nil; - (Class) classForCoder { - return [NSCharacterSet class]; + return abstractClass; } - (void) encodeWithCoder: (NSCoder*)aCoder @@ -524,6 +586,10 @@ static Class abstractMutableClass = nil; @end +#endif /* GNUSTEP_INDEX_CHARSET */ + + + @implementation NSCharacterSet + (void) initialize @@ -534,6 +600,13 @@ static Class abstractMutableClass = nil; { abstractClass = [NSCharacterSet class]; abstractMutableClass = [NSMutableCharacterSet class]; +#if defined(GNUSTEP_INDEX_CHARSET) + concreteClass = [_GSIndexCharSet class]; + concreteMutableClass = [_GSMutableIndexCharSet class]; +#else + concreteClass = [NSBitmapCharSet class]; + concreteMutableClass = [NSMutableBitmapCharSet class]; +#endif one_time = YES; } cache_lock = [GSLazyLock new]; @@ -544,7 +617,7 @@ static Class abstractMutableClass = nil; * using static bitmap data. * Return nil if no data is supplied and the cache is empty. */ -+ (NSCharacterSet*) _staticSet: (const unsigned char*)bytes ++ (NSCharacterSet*) _staticSet: (const void*)bytes length: (unsigned)length number: (int)number { @@ -557,7 +630,7 @@ static Class abstractMutableClass = nil; length: length freeWhenDone: NO]; cache_set[number] - = [[GSStaticCharSet alloc] initWithBitmap: bitmap number: number]; + = [[_GSStaticCharSet alloc] initWithBitmap: bitmap number: number]; RELEASE(bitmap); } [cache_lock unlock]; @@ -673,7 +746,7 @@ static Class abstractMutableClass = nil; + (NSCharacterSet*) characterSetWithBitmapRepresentation: (NSData*)data { - return AUTORELEASE([[NSBitmapCharSet alloc] initWithBitmap: data]); + return AUTORELEASE([[concreteClass alloc] initWithBitmap: data]); } + (NSCharacterSet*) characterSetWithCharactersInString: (NSString*)aString @@ -746,7 +819,7 @@ static Class abstractMutableClass = nil; { id obj; - obj = [NSBitmapCharSet allocWithZone: zone]; + obj = [concreteClass allocWithZone: zone]; obj = [obj initWithBitmap: [self bitmapRepresentation]]; return obj; } @@ -771,7 +844,7 @@ static Class abstractMutableClass = nil; { id obj; - obj = [NSBitmapCharSet allocWithZone: [self zone]]; + obj = [concreteClass allocWithZone: [self zone]]; obj = [obj initWithBitmap: nil]; RELEASE(self); self = obj; @@ -902,7 +975,7 @@ static Class abstractMutableClass = nil; { NSData *bitmap; bitmap = [self bitmapRepresentation]; - return [[NSMutableBitmapCharSet allocWithZone: zone] initWithBitmap: bitmap]; + return [[concreteMutableClass allocWithZone: zone] initWithBitmap: bitmap]; } @end @@ -912,7 +985,7 @@ static Class abstractMutableClass = nil; /* Override this from NSCharacterSet to create the correct class */ + (NSCharacterSet*) characterSetWithBitmapRepresentation: (NSData*)data { - return AUTORELEASE([[NSMutableBitmapCharSet alloc] initWithBitmap: data]); + return AUTORELEASE([[concreteMutableClass alloc] initWithBitmap: data]); } + (NSCharacterSet*) alphanumericCharacterSet @@ -1024,7 +1097,7 @@ static Class abstractMutableClass = nil; NSData *bitmap; bitmap = [self bitmapRepresentation]; - return [[NSBitmapCharSet allocWithZone: zone] initWithBitmap: bitmap]; + return [[concreteClass allocWithZone: zone] initWithBitmap: bitmap]; } - (void) formIntersectionWithCharacterSet: (NSCharacterSet*)otherSet @@ -1043,7 +1116,7 @@ static Class abstractMutableClass = nil; { id obj; - obj = [NSMutableBitmapCharSet allocWithZone: [self zone]]; + obj = [concreteMutableClass allocWithZone: [self zone]]; obj = [obj initWithBitmap: nil]; RELEASE(self); self = obj; @@ -1057,7 +1130,7 @@ static Class abstractMutableClass = nil; { id obj; - obj = [NSMutableBitmapCharSet allocWithZone: [self zone]]; + obj = [concreteMutableClass allocWithZone: [self zone]]; obj = [obj initWithBitmap: bitmap]; RELEASE(self); self = obj; @@ -1081,3 +1154,435 @@ static Class abstractMutableClass = nil; } @end + + +/* Below is an experimental implementation of a mutable character set + * implemented in terms of an NSMutableIndexSet. This should be much + * smaller than a bitmap representation for normal charactersets. + */ + +@interface NSIndexSet (NSCharacterSet) +- (unsigned int) _gapGreaterThanIndex: (unsigned int)anIndex; +@end + + +@implementation _GSIndexCharSet + +- (NSData*) bitmapRepresentation +{ + NSMutableBitmapCharSet *tmp; + NSData *result; + unsigned index = 0; + + tmp = [NSMutableBitmapCharSet new]; + while ((index = [indexes indexGreaterThanOrEqualToIndex: index]) + != NSNotFound) + { + NSRange r; + + r.location = index; + index = [indexes _gapGreaterThanIndex: index]; + if (index == NSNotFound) + { + r.length = 1; + } + else + { + r.length = index - r.location; + } + [tmp addCharactersInRange: r]; + index = NSMaxRange(r); + } + result = AUTORELEASE(RETAIN([tmp bitmapRepresentation])); + RELEASE(tmp); + return result; +} + +- (BOOL) characterIsMember: (unichar)aCharacter +{ + return [indexes containsIndex: (int)aCharacter]; +} + +- (Class) classForCoder +{ + return [NSBitmapCharSet class]; +} + +- (void) dealloc +{ + DESTROY(indexes); + [super dealloc]; +} + +- (void) encodeWithCoder: (NSCoder*)aCoder +{ + [aCoder encodeObject: [self bitmapRepresentation]]; +} + +- (BOOL) hasMemberInPlane: (uint8_t)aPlane +{ + unsigned found; + + found = [indexes indexGreaterThanOrEqualToIndex: 0x10000 * aPlane]; + if (found != NSNotFound && found < 0x10000 * (aPlane + 1)) + { + return YES; + } + return NO; +} + +- (NSIndexSet*) _indexes +{ + return indexes; +} + +- (id) init +{ + return [self initWithBitmap: nil]; +} + +- (id) initWithBitmap: (NSData*)bitmap +{ + const unsigned char *bytes = [bitmap bytes]; + unsigned length = [bitmap length]; + unsigned index = 0; + unsigned i; + NSRange r; + BOOL findingLocation = YES; + + indexes = [NSMutableIndexSet new]; + for (i = 0; i < length; i++) + { + unsigned char byte = bytes[i]; + + if (byte == 0) + { + if (findingLocation == NO) + { + r.length = index - r.location; + [indexes addIndexesInRange: r]; + findingLocation = YES; + } + index += 8; + } + else if (byte == 0xff) + { + if (findingLocation == YES) + { + r.location = index; + findingLocation = NO; + } + index += 8; + } + else + { + unsigned int bit; + + for (bit = 1; bit & 0xff; bit <<= 1) + { + if ((byte & bit) == 0) + { + if (findingLocation == NO) + { + r.length = index - r.location; + [indexes addIndexesInRange: r]; + findingLocation = YES; + } + } + else + { + if (findingLocation == YES) + { + r.location = index; + findingLocation = NO; + } + } + index++; + } + } + } + if (findingLocation == NO) + { + r.length = index - r.location; + [indexes addIndexesInRange: r]; + } + return self; +} + +- (id) initWithCoder: (NSCoder*)aCoder +{ + NSData *rep; + + rep = [aCoder decodeObject]; + self = [self initWithBitmap: rep]; + return self; +} + +- (BOOL) longCharacterIsMember: (UTF32Char)aCharacter +{ + return [indexes containsIndex: (int)aCharacter]; +} + +@end + +@implementation _GSMutableIndexCharSet + ++ (void) initialize +{ + if (self == [_GSMutableIndexCharSet class]) + { + [self setVersion: 1]; + GSObjCAddClassBehavior(self, [_GSIndexCharSet class]); + } +} + +- (void) addCharactersInRange: (NSRange)aRange +{ + if (NSMaxRange(aRange) > UNICODE_MAX) + { + [NSException raise:NSInvalidArgumentException + format:@"Specified range exceeds character set"]; + /* NOT REACHED */ + } + [indexes addIndexesInRange: aRange]; +} + +- (void) addCharactersInString: (NSString*)aString +{ + unsigned length; + + if (!aString) + { + [NSException raise:NSInvalidArgumentException + format:@"Adding characters from nil string"]; + /* NOT REACHED */ + } + + length = [aString length]; + if (length > 0) + { + unsigned i; + unichar (*get)(id, SEL, unsigned); + + get = (unichar (*)(id, SEL, unsigned)) + [aString methodForSelector: @selector(characterAtIndex:)]; + for (i = 0; i < length; i++) + { + unichar letter; + unichar second; + + letter = (*get)(aString, @selector(characterAtIndex:), i); + // Convert a surrogate pair if necessary + if (letter >= 0xd800 && letter <= 0xdbff && i < length-1 + && (second = (*get)(aString, @selector(characterAtIndex:), i+1)) + >= 0xdc00 && second <= 0xdfff) + { + i++; + letter = ((letter - 0xd800) << 10) + + (second - 0xdc00) + 0x0010000; + } + [indexes addIndexesInRange: NSMakeRange(letter, 1)]; + } + } +} + +- (Class) classForCoder +{ + return [NSMutableBitmapCharSet class]; +} + +- (void) formIntersectionWithCharacterSet: (NSCharacterSet *)otherSet +{ + NSIndexSet *otherIndexes; + unsigned index = 0; + unsigned i0; + unsigned i1; + + if ([otherSet isKindOfClass: [_GSIndexCharSet class]] == YES) + { + otherIndexes = [(_GSIndexCharSet*)otherSet _indexes]; + } + else + { + _GSIndexCharSet *tmp; + + tmp = [[_GSIndexCharSet alloc] initWithBitmap: + [otherSet bitmapRepresentation]]; + otherIndexes = AUTORELEASE(RETAIN([tmp _indexes])); + RELEASE(tmp); + } + + /* Find first index in each set. + */ + i0 = [indexes indexGreaterThanOrEqualToIndex: 0]; + i1 = [otherIndexes indexGreaterThanOrEqualToIndex: 0]; + + /* Loop until there are no more indexes to process in the set and + * the intersection operation has therefore completed. + */ + while (i0 != NSNotFound) + { + if (i1 == NSNotFound) + { + /* No more indexes in other set ... remove everything from the + * last gap onwards, and finish. + */ + [indexes removeIndexesInRange: NSMakeRange(index, NSNotFound-index)]; + break; + } + if (i1 > i0) + { + /* Indexes in other set start after this set ... so remove any + * from the last gap to the index in the other set. + */ + [indexes removeIndexesInRange: NSMakeRange(index, i1 - index)]; + index = i1; + } + else + { + index = i0; + } + + /* Find the next gap in each set, and set our gap index to the + * lower of the two. + */ + i0 = [indexes _gapGreaterThanIndex: index]; + i1 = [otherIndexes _gapGreaterThanIndex: index]; + index = i0; + if (i1 < i0) + { + index = i1; + } + + /* Find the next index in each set so wer can loop round and + * do it all again. + */ + i0 = [indexes indexGreaterThanIndex: i0]; + i1 = [otherIndexes indexGreaterThanIndex: i1]; + } +} + +- (void) formUnionWithCharacterSet: (NSCharacterSet*)otherSet +{ + NSIndexSet *otherIndexes; + unsigned index; + + if ([otherSet isKindOfClass: [_GSIndexCharSet class]] == YES) + { + otherIndexes = [(_GSIndexCharSet*)otherSet _indexes]; + } + else + { + _GSIndexCharSet *tmp; + + tmp = [[_GSIndexCharSet alloc] initWithBitmap: + [otherSet bitmapRepresentation]]; + otherIndexes = AUTORELEASE(RETAIN([tmp _indexes])); + RELEASE(tmp); + } + + index = [otherIndexes indexGreaterThanOrEqualToIndex: 0]; + while (index != NSNotFound) + { + NSRange r; + + r.location = index; + index = [otherIndexes _gapGreaterThanIndex: index]; + r.length = index - r.location; + [indexes addIndexesInRange: r]; + index = [otherIndexes indexGreaterThanOrEqualToIndex: index]; + } +} + +- (void) invert +{ + NSMutableIndexSet *tmp; + unsigned index; + + tmp = [NSMutableIndexSet new]; + + /* Locate the start of the first gap + */ + if ([indexes containsIndex: 0] == YES) + { + index = [indexes _gapGreaterThanIndex: 0]; + } + else + { + index = 0; + } + + while (index != NSNotFound) + { + NSRange r; + + r.location = index; + index = [indexes indexGreaterThanIndex: index]; + if (index == NSNotFound) + { + /* No more indexes, so we have a gap to the end of all + * unicode characters which we can invert. + */ + index = UNICODE_MAX; + } + r.length = index - r.location; + [tmp addIndexesInRange: r]; + index = [indexes _gapGreaterThanIndex: NSMaxRange(r) - 1]; + } + ASSIGN(indexes, tmp); + RELEASE(tmp); +} + +- (void) removeCharactersInRange: (NSRange)aRange +{ + if (NSMaxRange(aRange) > UNICODE_MAX) + { + [NSException raise:NSInvalidArgumentException + format:@"Specified range exceeds character set"]; + /* NOT REACHED */ + } + [indexes removeIndexesInRange: aRange]; +} + +- (void) removeCharactersInString: (NSString*)aString +{ + unsigned length; + + if (!aString) + { + [NSException raise:NSInvalidArgumentException + format:@"Removing characters from nil string"]; + /* NOT REACHED */ + } + + length = [aString length]; + if (length > 0) + { + unsigned i; + unichar (*get)(id, SEL, unsigned); + + get = (unichar (*)(id, SEL, unsigned)) + [aString methodForSelector: @selector(characterAtIndex:)]; + + for (i = 0; i < length; i++) + { + unichar letter; + unichar second; + + letter = (*get)(aString, @selector(characterAtIndex:), i); + // Convert a surrogate pair if necessary + if (letter >= 0xd800 && letter <= 0xdbff && i < length-1 + && (second = (*get)(aString, @selector(characterAtIndex:), i+1)) + >= 0xdc00 && second <= 0xdfff) + { + i++; + letter = ((letter - 0xd800) << 10) + + (second - 0xdc00) + 0x0010000; + } + [indexes removeIndexesInRange: NSMakeRange(letter, 1)]; + } + } +} + +@end + diff --git a/Source/NSCharacterSetData.h b/Source/NSCharacterSetData.h index 2ee56a11e..bdb590847 100644 --- a/Source/NSCharacterSetData.h +++ b/Source/NSCharacterSetData.h @@ -11,6 +11,476 @@ * gnustep system and speeding up startup of GNUstep * processes. */ +#if defined(GNUSTEP_INDEX_CHARSET) +static const unsigned int alphanumericCharSet[] = { +48,10, +65,26, +97,26, +170,1, +178,2, +181,1, +185,2, +188,3, +192,23, +216,31, +248,458, +710,12, +736,5, +750,1, +768,112, +890,4, +902,1, +904,3, +908,1, +910,20, +931,44, +976,38, +1015,139, +1155,4, +1160,140, +1329,38, +1369,1, +1377,39, +1425,45, +1471,1, +1473,2, +1476,2, +1479,1, +1488,27, +1520,3, +1552,6, +1569,26, +1600,31, +1632,10, +1646,102, +1749,8, +1758,11, +1770,19, +1791,1, +1808,59, +1869,33, +1920,50, +1984,54, +2042,1, +2305,57, +2364,18, +2384,5, +2392,12, +2406,10, +2427,5, +2433,3, +2437,8, +2447,2, +2451,22, +2474,7, +2482,1, +2486,4, +2492,9, +2503,2, +2507,4, +2519,1, +2524,2, +2527,5, +2534,12, +2548,6, +2561,3, +2565,6, +2575,2, +2579,22, +2602,7, +2610,2, +2613,2, +2616,2, +2620,1, +2622,5, +2631,2, +2635,3, +2649,4, +2654,1, +2662,15, +2689,3, +2693,9, +2703,3, +2707,22, +2730,7, +2738,2, +2741,5, +2748,10, +2759,3, +2763,3, +2768,1, +2784,4, +2790,10, +2817,3, +2821,8, +2831,2, +2835,22, +2858,7, +2866,2, +2869,5, +2876,8, +2887,2, +2891,3, +2902,2, +2908,2, +2911,3, +2918,10, +2929,1, +2946,2, +2949,6, +2958,3, +2962,4, +2969,2, +2972,1, +2974,2, +2979,2, +2984,3, +2990,12, +3006,5, +3014,3, +3018,4, +3031,1, +3046,13, +3073,3, +3077,8, +3086,3, +3090,23, +3114,10, +3125,5, +3134,7, +3142,3, +3146,4, +3157,2, +3168,2, +3174,10, +3202,2, +3205,8, +3214,3, +3218,23, +3242,10, +3253,5, +3260,9, +3270,3, +3274,4, +3285,2, +3294,1, +3296,4, +3302,10, +3330,2, +3333,8, +3342,3, +3346,23, +3370,16, +3390,6, +3398,3, +3402,4, +3415,1, +3424,2, +3430,10, +3458,2, +3461,18, +3482,24, +3507,9, +3517,1, +3520,7, +3530,1, +3535,6, +3542,1, +3544,8, +3570,2, +3585,58, +3648,15, +3664,10, +3713,2, +3716,1, +3719,2, +3722,1, +3725,1, +3732,4, +3737,7, +3745,3, +3749,1, +3751,1, +3754,2, +3757,13, +3771,3, +3776,5, +3782,1, +3784,6, +3792,10, +3804,2, +3840,1, +3864,2, +3872,20, +3893,1, +3895,1, +3897,1, +3902,10, +3913,34, +3953,20, +3974,6, +3984,8, +3993,36, +4038,1, +4096,34, +4131,5, +4137,2, +4140,7, +4150,4, +4160,10, +4176,10, +4256,38, +4304,43, +4348,1, +4352,90, +4447,68, +4520,82, +4608,73, +4682,4, +4688,7, +4696,1, +4698,4, +4704,41, +4746,4, +4752,33, +4786,4, +4792,7, +4800,1, +4802,4, +4808,15, +4824,57, +4882,4, +4888,67, +4959,1, +4969,20, +4992,16, +5024,85, +5121,620, +5743,8, +5761,26, +5792,75, +5870,3, +5888,13, +5902,7, +5920,21, +5952,20, +5984,13, +5998,3, +6002,2, +6016,52, +6070,30, +6103,1, +6108,2, +6112,10, +6128,10, +6155,3, +6160,10, +6176,88, +6272,42, +6400,29, +6432,12, +6448,12, +6470,40, +6512,5, +6528,42, +6576,26, +6608,10, +6656,28, +6912,76, +6992,10, +7019,9, +7424,203, +7678,158, +7840,90, +7936,22, +7960,6, +7968,38, +8008,6, +8016,8, +8025,1, +8027,1, +8029,1, +8031,31, +8064,53, +8118,7, +8126,1, +8130,3, +8134,7, +8144,4, +8150,6, +8160,13, +8178,3, +8182,7, +8304,2, +8308,6, +8319,11, +8336,5, +8400,32, +8450,1, +8455,1, +8458,10, +8469,1, +8473,5, +8484,1, +8486,1, +8488,1, +8490,4, +8495,11, +8508,4, +8517,5, +8526,1, +8531,50, +9312,60, +9450,22, +10102,30, +11264,47, +11312,47, +11360,13, +11380,4, +11392,101, +11517,1, +11520,38, +11568,54, +11631,1, +11648,23, +11680,7, +11688,7, +11696,7, +11704,7, +11712,7, +11720,7, +11728,7, +11736,7, +12293,3, +12321,15, +12337,5, +12344,5, +12353,86, +12441,2, +12445,3, +12449,90, +12540,4, +12549,40, +12593,94, +12690,4, +12704,24, +12784,16, +12832,10, +12881,15, +12928,10, +12977,15, +13312,6581, +19968,20923, +40960,1165, +42775,4, +43008,40, +43072,52, +44032,11171, +63744,302, +64048,59, +64112,106, +64256,7, +64275,5, +64285,12, +64298,13, +64312,5, +64318,1, +64320,2, +64323,2, +64326,108, +64467,363, +64848,64, +64914,54, +65008,12, +65024,16, +65056,4, +65136,5, +65142,135, +65296,10, +65313,26, +65345,26, +65382,89, +65474,6, +65482,6, +65490,6, +65498,3, +65536,12, +65549,26, +65576,19, +65596,2, +65599,15, +65616,14, +65664,123, +65799,45, +65856,57, +65930,1, +66304,31, +66336,4, +66352,27, +66432,30, +66464,36, +66504,8, +66513,5, +66560,158, +66720,10, +67584,6, +67592,1, +67594,44, +67639,2, +67644,1, +67647,1, +67840,26, +68096,4, +68101,2, +68108,8, +68117,3, +68121,27, +68152,3, +68159,9, +73728,879, +74752,99, +119141,5, +119149,6, +119163,8, +119173,7, +119210,4, +119362,3, +119648,18, +119808,85, +119894,71, +119966,2, +119970,1, +119973,2, +119977,4, +119982,12, +119995,1, +119997,7, +120005,65, +120071,4, +120077,8, +120086,7, +120094,28, +120123,4, +120128,5, +120134,1, +120138,7, +120146,340, +120488,25, +120514,25, +120540,31, +120572,25, +120598,31, +120630,25, +120656,31, +120688,25, +120714,31, +120746,25, +120772,8, +120782,50, +131072,42710, +194560,542, +917760,240}; +#else /* GNUSTEP_INDEX_CHARSET */ static const unsigned char alphanumericCharSet[122880] = { '\x00', '\x00', @@ -122892,6 +123362,26 @@ static const unsigned char alphanumericCharSet[122880] = { '\x00', '\x00', '\x00'}; +#endif /* GNUSTEP_INDEX_CHARSET */ +#if defined(GNUSTEP_INDEX_CHARSET) +static const unsigned int controlCharSet[] = { +0,32, +127,33, +173,1, +1536,4, +1757,1, +1807,1, +6068,2, +8203,5, +8234,5, +8288,4, +8298,6, +65279,1, +65529,3, +119155,8, +917505,1, +917536,96}; +#else /* GNUSTEP_INDEX_CHARSET */ static const unsigned char controlCharSet[122880] = { '\xff', '\xff', @@ -245773,6 +246263,35 @@ static const unsigned char controlCharSet[122880] = { '\x00', '\x00', '\x00'}; +#endif /* GNUSTEP_INDEX_CHARSET */ +#if defined(GNUSTEP_INDEX_CHARSET) +static const unsigned int decimalDigitCharSet[] = { +48,10, +1632,10, +1776,10, +1984,10, +2406,10, +2534,10, +2662,10, +2790,10, +2918,10, +3046,10, +3174,10, +3302,10, +3430,10, +3664,10, +3792,10, +3872,10, +4160,10, +6112,10, +6160,10, +6470,10, +6608,10, +6992,10, +65296,10, +66720,10, +120782,50}; +#else /* GNUSTEP_INDEX_CHARSET */ static const unsigned char decimalDigitCharSet[16384] = { '\x00', '\x00', @@ -262158,6 +262677,344 @@ static const unsigned char decimalDigitCharSet[16384] = { '\x00', '\x00', '\x00'}; +#endif /* GNUSTEP_INDEX_CHARSET */ +#if defined(GNUSTEP_INDEX_CHARSET) +static const unsigned int decomposableCharSet[] = { +160,1, +168,1, +170,1, +175,1, +178,4, +184,3, +188,3, +192,6, +199,9, +209,6, +217,5, +224,6, +231,9, +241,6, +249,5, +255,17, +274,20, +296,9, +306,6, +313,8, +323,7, +332,6, +340,18, +360,24, +416,2, +431,2, +452,25, +478,6, +486,16, +504,36, +542,2, +550,14, +688,9, +728,6, +736,5, +832,2, +835,2, +884,1, +890,1, +894,1, +900,7, +908,1, +910,3, +938,7, +970,5, +976,7, +1008,3, +1012,2, +1017,1, +1024,2, +1027,1, +1031,1, +1036,3, +1049,1, +1081,1, +1104,2, +1107,1, +1111,1, +1116,3, +1142,2, +1217,2, +1232,4, +1238,2, +1242,6, +1250,6, +1258,12, +1272,2, +1415,1, +1570,5, +1653,4, +1728,1, +1730,1, +1747,1, +2345,1, +2353,1, +2356,1, +2392,8, +2507,2, +2524,2, +2527,1, +2611,1, +2614,1, +2649,3, +2654,1, +2888,1, +2891,2, +2908,2, +2964,1, +3018,3, +3144,1, +3264,1, +3271,2, +3274,2, +3402,3, +3546,1, +3548,3, +3635,1, +3763,1, +3804,2, +3852,1, +3907,1, +3917,1, +3922,1, +3927,1, +3932,1, +3945,1, +3955,1, +3957,5, +3969,1, +3987,1, +3997,1, +4002,1, +4007,1, +4012,1, +4025,1, +4134,1, +4348,1, +6918,1, +6920,1, +6922,1, +6924,1, +6926,1, +6930,1, +6971,1, +6973,1, +6976,2, +6979,1, +7468,3, +7472,11, +7484,18, +7503,28, +7544,1, +7579,37, +7680,156, +7840,90, +7936,22, +7960,6, +7968,38, +8008,6, +8016,8, +8025,1, +8027,1, +8029,1, +8031,31, +8064,53, +8118,15, +8134,14, +8150,6, +8157,19, +8178,3, +8182,9, +8192,11, +8209,1, +8215,1, +8228,3, +8239,1, +8243,2, +8246,2, +8252,1, +8254,1, +8263,3, +8279,1, +8287,1, +8304,2, +8308,27, +8336,5, +8360,1, +8448,4, +8453,3, +8457,11, +8469,2, +8473,5, +8480,3, +8484,1, +8486,1, +8488,1, +8490,4, +8495,3, +8499,7, +8507,6, +8517,5, +8531,45, +8602,2, +8622,1, +8653,3, +8708,1, +8713,1, +8716,1, +8740,1, +8742,1, +8748,2, +8751,2, +8769,1, +8772,1, +8775,1, +8777,1, +8800,1, +8802,1, +8813,5, +8820,2, +8824,2, +8832,2, +8836,2, +8840,2, +8876,4, +8928,4, +8938,4, +9001,2, +9312,139, +10764,1, +10868,3, +10972,1, +11631,1, +11935,1, +12019,1, +12032,214, +12288,1, +12342,1, +12344,3, +12364,1, +12366,1, +12368,1, +12370,1, +12372,1, +12374,1, +12376,1, +12378,1, +12380,1, +12382,1, +12384,1, +12386,1, +12389,1, +12391,1, +12393,1, +12400,2, +12403,2, +12406,2, +12409,2, +12412,2, +12436,1, +12443,2, +12446,2, +12460,1, +12462,1, +12464,1, +12466,1, +12468,1, +12470,1, +12472,1, +12474,1, +12476,1, +12478,1, +12480,1, +12482,1, +12485,1, +12487,1, +12489,1, +12496,2, +12499,2, +12502,2, +12505,2, +12508,2, +12532,1, +12535,4, +12542,2, +12593,94, +12690,14, +12800,31, +12832,36, +12880,47, +12928,127, +13056,256, +63744,270, +64016,1, +64018,1, +64021,10, +64032,1, +64034,1, +64037,2, +64042,4, +64048,59, +64112,106, +64256,7, +64275,5, +64285,1, +64287,24, +64312,5, +64318,1, +64320,2, +64323,2, +64326,108, +64467,363, +64848,64, +64914,54, +65008,13, +65040,10, +65072,21, +65095,12, +65108,19, +65128,4, +65136,3, +65140,1, +65142,135, +65281,190, +65474,6, +65482,6, +65490,6, +65498,3, +65504,7, +65512,7, +119134,7, +119227,6, +119808,85, +119894,71, +119966,2, +119970,1, +119973,2, +119977,4, +119982,12, +119995,1, +119997,7, +120005,65, +120071,4, +120077,8, +120086,7, +120094,28, +120123,4, +120128,5, +120134,1, +120138,7, +120146,340, +120488,292, +120782,50, +194560,542}; +#else /* GNUSTEP_INDEX_CHARSET */ static const unsigned char decomposableCharSet[24576] = { '\x00', '\x00', @@ -286735,6 +287592,444 @@ static const unsigned char decomposableCharSet[24576] = { '\x00', '\x00', '\x00'}; +#endif /* GNUSTEP_INDEX_CHARSET */ +#if defined(GNUSTEP_INDEX_CHARSET) +static const unsigned int illegalCharSet[] = { +880,4, +886,4, +895,5, +907,1, +909,1, +930,1, +975,1, +1159,1, +1300,29, +1367,2, +1376,1, +1416,1, +1419,6, +1480,8, +1515,5, +1525,11, +1540,7, +1558,5, +1564,2, +1568,1, +1595,5, +1631,1, +1806,1, +1867,2, +1902,18, +1970,14, +2043,262, +2362,2, +2382,2, +2389,3, +2417,10, +2432,1, +2436,1, +2445,2, +2449,2, +2473,1, +2481,1, +2483,3, +2490,2, +2501,2, +2505,2, +2511,8, +2520,4, +2526,1, +2532,2, +2555,6, +2564,1, +2571,4, +2577,2, +2601,1, +2609,1, +2612,1, +2615,1, +2618,2, +2621,1, +2627,4, +2633,2, +2638,11, +2653,1, +2655,7, +2677,12, +2692,1, +2702,1, +2706,1, +2729,1, +2737,1, +2740,1, +2746,2, +2758,1, +2762,1, +2766,2, +2769,15, +2788,2, +2800,1, +2802,15, +2820,1, +2829,2, +2833,2, +2857,1, +2865,1, +2868,1, +2874,2, +2884,3, +2889,2, +2894,8, +2904,4, +2910,1, +2914,4, +2930,16, +2948,1, +2955,3, +2961,1, +2966,3, +2971,1, +2973,1, +2976,3, +2981,3, +2987,3, +3002,4, +3011,3, +3017,1, +3022,9, +3032,14, +3067,6, +3076,1, +3085,1, +3089,1, +3113,1, +3124,1, +3130,4, +3141,1, +3145,1, +3150,7, +3159,9, +3170,4, +3184,18, +3204,1, +3213,1, +3217,1, +3241,1, +3252,1, +3258,2, +3269,1, +3273,1, +3278,7, +3287,7, +3295,1, +3300,2, +3312,1, +3315,15, +3332,1, +3341,1, +3345,1, +3369,1, +3386,4, +3396,2, +3401,1, +3406,9, +3416,8, +3426,4, +3440,18, +3460,1, +3479,3, +3506,1, +3516,1, +3518,2, +3527,3, +3531,4, +3541,1, +3543,1, +3552,18, +3573,12, +3643,4, +3676,37, +3715,1, +3717,2, +3721,1, +3723,2, +3726,6, +3736,1, +3744,1, +3748,1, +3750,1, +3752,2, +3756,1, +3770,1, +3774,2, +3781,1, +3783,1, +3790,2, +3802,2, +3806,34, +3912,1, +3947,6, +3980,4, +3992,1, +4029,1, +4045,2, +4050,46, +4130,1, +4136,1, +4139,1, +4147,3, +4154,6, +4186,70, +4294,10, +4349,3, +4442,5, +4515,5, +4602,6, +4681,1, +4686,2, +4695,1, +4697,1, +4702,2, +4745,1, +4750,2, +4785,1, +4790,2, +4799,1, +4801,1, +4806,2, +4823,1, +4881,1, +4886,2, +4955,4, +4989,3, +5018,6, +5109,12, +5751,9, +5789,3, +5873,15, +5901,1, +5909,11, +5943,9, +5972,12, +5997,1, +6001,1, +6004,12, +6110,2, +6122,6, +6138,6, +6159,1, +6170,6, +6264,8, +6314,86, +6429,3, +6444,4, +6460,4, +6465,3, +6510,2, +6517,11, +6570,6, +6602,6, +6618,4, +6684,2, +6688,224, +6988,4, +7037,387, +7627,51, +7836,4, +7930,6, +7958,2, +7966,2, +8006,2, +8014,2, +8024,1, +8026,1, +8028,1, +8030,1, +8062,2, +8117,1, +8133,1, +8148,2, +8156,1, +8176,2, +8181,1, +8191,1, +8292,6, +8306,2, +8335,1, +8341,11, +8374,26, +8432,16, +8527,4, +8581,11, +9192,24, +9255,25, +9291,21, +9885,3, +9907,78, +9989,1, +9994,2, +10024,1, +10060,1, +10062,1, +10067,3, +10071,1, +10079,2, +10133,3, +10160,1, +10175,1, +10187,5, +10220,4, +11035,5, +11044,220, +11311,1, +11359,1, +11373,7, +11384,8, +11499,14, +11558,10, +11622,9, +11632,16, +11671,9, +11687,1, +11695,1, +11703,1, +11711,1, +11719,1, +11727,1, +11735,1, +11743,33, +11800,4, +11806,98, +11930,1, +12020,12, +12246,26, +12284,4, +12352,1, +12439,2, +12544,5, +12589,4, +12687,1, +12728,8, +12752,32, +12831,1, +12868,12, +13055,1, +19893,11, +40891,69, +42125,3, +42183,569, +42779,5, +42786,222, +43052,20, +43128,904, +55203,93, +56191,1, +56319,1, +57343,1, +63743,1, +64046,2, +64107,5, +64218,38, +64263,12, +64280,5, +64311,1, +64317,1, +64319,1, +64322,1, +64325,1, +64434,33, +64832,16, +64912,2, +64968,40, +65022,2, +65050,6, +65060,12, +65107,1, +65127,1, +65132,4, +65141,1, +65277,2, +65280,1, +65471,3, +65480,2, +65488,2, +65496,2, +65501,3, +65511,1, +65519,10, +65534,2, +65548,1, +65575,1, +65595,1, +65598,1, +65614,2, +65630,34, +65787,5, +65795,4, +65844,3, +65931,373, +66335,1, +66340,12, +66379,53, +66462,1, +66500,4, +66518,42, +66718,2, +66730,854, +67590,2, +67593,1, +67638,1, +67641,3, +67645,2, +67648,192, +67866,5, +67872,224, +68100,1, +68103,5, +68116,1, +68120,1, +68148,4, +68155,4, +68168,8, +68185,5543, +74607,145, +74851,13, +74868,43916, +119030,10, +119079,3, +119262,34, +119366,186, +119639,9, +119666,142, +119893,1, +119965,1, +119968,2, +119971,2, +119975,2, +119981,1, +119994,1, +119996,1, +120004,1, +120070,1, +120075,2, +120085,1, +120093,1, +120122,1, +120127,1, +120133,1, +120135,3, +120145,1, +120486,2, +120780,2, +120832,10240, +173782,20778, +195102,722403, +917506,30, +917632,128, +918000,65040, +1048573,3, +1114109,3}; +#else /* GNUSTEP_INDEX_CHARSET */ static const unsigned char illegalCharSet[139264] = { '\x00', '\x00', @@ -426000,6 +427295,460 @@ static const unsigned char illegalCharSet[139264] = { '\x00', '\x00', '\xe0'}; +#endif /* GNUSTEP_INDEX_CHARSET */ +#if defined(GNUSTEP_INDEX_CHARSET) +static const unsigned int letterCharSet[] = { +65,26, +97,26, +170,1, +178,2, +181,1, +185,2, +188,3, +192,23, +216,31, +248,458, +710,12, +736,5, +750,1, +768,112, +890,4, +902,1, +904,3, +908,1, +910,20, +931,44, +976,38, +1015,139, +1155,4, +1160,140, +1329,38, +1369,1, +1377,39, +1425,45, +1471,1, +1473,2, +1476,2, +1479,1, +1488,27, +1520,3, +1552,6, +1569,26, +1600,31, +1646,102, +1749,8, +1758,11, +1770,6, +1786,3, +1791,1, +1808,59, +1869,33, +1920,50, +1994,44, +2042,1, +2305,57, +2364,18, +2384,5, +2392,12, +2427,5, +2433,3, +2437,8, +2447,2, +2451,22, +2474,7, +2482,1, +2486,4, +2492,9, +2503,2, +2507,4, +2519,1, +2524,2, +2527,5, +2544,2, +2548,6, +2561,3, +2565,6, +2575,2, +2579,22, +2602,7, +2610,2, +2613,2, +2616,2, +2620,1, +2622,5, +2631,2, +2635,3, +2649,4, +2654,1, +2672,5, +2689,3, +2693,9, +2703,3, +2707,22, +2730,7, +2738,2, +2741,5, +2748,10, +2759,3, +2763,3, +2768,1, +2784,4, +2817,3, +2821,8, +2831,2, +2835,22, +2858,7, +2866,2, +2869,5, +2876,8, +2887,2, +2891,3, +2902,2, +2908,2, +2911,3, +2929,1, +2946,2, +2949,6, +2958,3, +2962,4, +2969,2, +2972,1, +2974,2, +2979,2, +2984,3, +2990,12, +3006,5, +3014,3, +3018,4, +3031,1, +3056,3, +3073,3, +3077,8, +3086,3, +3090,23, +3114,10, +3125,5, +3134,7, +3142,3, +3146,4, +3157,2, +3168,2, +3202,2, +3205,8, +3214,3, +3218,23, +3242,10, +3253,5, +3260,9, +3270,3, +3274,4, +3285,2, +3294,1, +3296,4, +3330,2, +3333,8, +3342,3, +3346,23, +3370,16, +3390,6, +3398,3, +3402,4, +3415,1, +3424,2, +3458,2, +3461,18, +3482,24, +3507,9, +3517,1, +3520,7, +3530,1, +3535,6, +3542,1, +3544,8, +3570,2, +3585,58, +3648,15, +3713,2, +3716,1, +3719,2, +3722,1, +3725,1, +3732,4, +3737,7, +3745,3, +3749,1, +3751,1, +3754,2, +3757,13, +3771,3, +3776,5, +3782,1, +3784,6, +3804,2, +3840,1, +3864,2, +3882,10, +3893,1, +3895,1, +3897,1, +3902,10, +3913,34, +3953,20, +3974,6, +3984,8, +3993,36, +4038,1, +4096,34, +4131,5, +4137,2, +4140,7, +4150,4, +4176,10, +4256,38, +4304,43, +4348,1, +4352,90, +4447,68, +4520,82, +4608,73, +4682,4, +4688,7, +4696,1, +4698,4, +4704,41, +4746,4, +4752,33, +4786,4, +4792,7, +4800,1, +4802,4, +4808,15, +4824,57, +4882,4, +4888,67, +4959,1, +4969,20, +4992,16, +5024,85, +5121,620, +5743,8, +5761,26, +5792,75, +5870,3, +5888,13, +5902,7, +5920,21, +5952,20, +5984,13, +5998,3, +6002,2, +6016,52, +6070,30, +6103,1, +6108,2, +6128,10, +6155,3, +6176,88, +6272,42, +6400,29, +6432,12, +6448,12, +6480,30, +6512,5, +6528,42, +6576,26, +6656,28, +6912,76, +7019,9, +7424,203, +7678,158, +7840,90, +7936,22, +7960,6, +7968,38, +8008,6, +8016,8, +8025,1, +8027,1, +8029,1, +8031,31, +8064,53, +8118,7, +8126,1, +8130,3, +8134,7, +8144,4, +8150,6, +8160,13, +8178,3, +8182,7, +8304,2, +8308,6, +8319,11, +8336,5, +8400,32, +8450,1, +8455,1, +8458,10, +8469,1, +8473,5, +8484,1, +8486,1, +8488,1, +8490,4, +8495,11, +8508,4, +8517,5, +8526,1, +8531,50, +9312,60, +9450,22, +10102,30, +11264,47, +11312,47, +11360,13, +11380,4, +11392,101, +11517,1, +11520,38, +11568,54, +11631,1, +11648,23, +11680,7, +11688,7, +11696,7, +11704,7, +11712,7, +11720,7, +11728,7, +11736,7, +12293,3, +12321,15, +12337,5, +12344,5, +12353,86, +12441,2, +12445,3, +12449,90, +12540,4, +12549,40, +12593,94, +12690,4, +12704,24, +12784,16, +12832,10, +12881,15, +12928,10, +12977,15, +13312,6581, +19968,20923, +40960,1165, +42775,4, +43008,40, +43072,52, +44032,11171, +63744,302, +64048,59, +64112,106, +64256,7, +64275,5, +64285,12, +64298,13, +64312,5, +64318,1, +64320,2, +64323,2, +64326,108, +64467,363, +64848,64, +64914,54, +65008,12, +65024,16, +65056,4, +65136,5, +65142,135, +65313,26, +65345,26, +65382,89, +65474,6, +65482,6, +65490,6, +65498,3, +65536,12, +65549,26, +65576,19, +65596,2, +65599,15, +65616,14, +65664,123, +65799,45, +65856,57, +65930,1, +66304,31, +66336,4, +66352,27, +66432,30, +66464,36, +66504,8, +66513,5, +66560,158, +67584,6, +67592,1, +67594,44, +67639,2, +67644,1, +67647,1, +67840,26, +68096,4, +68101,2, +68108,8, +68117,3, +68121,27, +68152,3, +68159,9, +73728,879, +74752,99, +119141,5, +119149,6, +119163,8, +119173,7, +119210,4, +119362,3, +119648,18, +119808,85, +119894,71, +119966,2, +119970,1, +119973,2, +119977,4, +119982,12, +119995,1, +119997,7, +120005,65, +120071,4, +120077,8, +120086,7, +120094,28, +120123,4, +120128,5, +120134,1, +120138,7, +120146,340, +120488,25, +120514,25, +120540,31, +120572,25, +120598,31, +120630,25, +120656,31, +120688,25, +120714,31, +120746,25, +120772,8, +131072,42710, +194560,542, +917760,240}; +#else /* GNUSTEP_INDEX_CHARSET */ static const unsigned char letterCharSet[122880] = { '\x00', '\x00', @@ -548881,6 +550630,512 @@ static const unsigned char letterCharSet[122880] = { '\x00', '\x00', '\x00'}; +#endif /* GNUSTEP_INDEX_CHARSET */ +#if defined(GNUSTEP_INDEX_CHARSET) +static const unsigned int lowercaseLetterCharSet[] = { +97,26, +170,1, +181,1, +186,1, +223,24, +248,8, +257,1, +259,1, +261,1, +263,1, +265,1, +267,1, +269,1, +271,1, +273,1, +275,1, +277,1, +279,1, +281,1, +283,1, +285,1, +287,1, +289,1, +291,1, +293,1, +295,1, +297,1, +299,1, +301,1, +303,1, +305,1, +307,1, +309,1, +311,2, +314,1, +316,1, +318,1, +320,1, +322,1, +324,1, +326,1, +328,2, +331,1, +333,1, +335,1, +337,1, +339,1, +341,1, +343,1, +345,1, +347,1, +349,1, +351,1, +353,1, +355,1, +357,1, +359,1, +361,1, +363,1, +365,1, +367,1, +369,1, +371,1, +373,1, +375,1, +378,1, +380,1, +382,3, +387,1, +389,1, +392,1, +396,2, +402,1, +405,1, +409,3, +414,1, +417,1, +419,1, +421,1, +424,1, +426,2, +429,1, +432,1, +436,1, +438,1, +441,2, +445,3, +454,1, +457,1, +460,1, +462,1, +464,1, +466,1, +468,1, +470,1, +472,1, +474,1, +476,2, +479,1, +481,1, +483,1, +485,1, +487,1, +489,1, +491,1, +493,1, +495,2, +499,1, +501,1, +505,1, +507,1, +509,1, +511,1, +513,1, +515,1, +517,1, +519,1, +521,1, +523,1, +525,1, +527,1, +529,1, +531,1, +533,1, +535,1, +537,1, +539,1, +541,1, +543,1, +545,1, +547,1, +549,1, +551,1, +553,1, +555,1, +557,1, +559,1, +561,1, +563,7, +572,1, +575,2, +578,1, +583,1, +585,1, +587,1, +589,1, +591,69, +661,27, +891,3, +912,1, +940,35, +976,2, +981,3, +985,1, +987,1, +989,1, +991,1, +993,1, +995,1, +997,1, +999,1, +1001,1, +1003,1, +1005,1, +1007,5, +1013,1, +1016,1, +1019,2, +1072,48, +1121,1, +1123,1, +1125,1, +1127,1, +1129,1, +1131,1, +1133,1, +1135,1, +1137,1, +1139,1, +1141,1, +1143,1, +1145,1, +1147,1, +1149,1, +1151,1, +1153,1, +1163,1, +1165,1, +1167,1, +1169,1, +1171,1, +1173,1, +1175,1, +1177,1, +1179,1, +1181,1, +1183,1, +1185,1, +1187,1, +1189,1, +1191,1, +1193,1, +1195,1, +1197,1, +1199,1, +1201,1, +1203,1, +1205,1, +1207,1, +1209,1, +1211,1, +1213,1, +1215,1, +1218,1, +1220,1, +1222,1, +1224,1, +1226,1, +1228,1, +1230,2, +1233,1, +1235,1, +1237,1, +1239,1, +1241,1, +1243,1, +1245,1, +1247,1, +1249,1, +1251,1, +1253,1, +1255,1, +1257,1, +1259,1, +1261,1, +1263,1, +1265,1, +1267,1, +1269,1, +1271,1, +1273,1, +1275,1, +1277,1, +1279,1, +1281,1, +1283,1, +1285,1, +1287,1, +1289,1, +1291,1, +1293,1, +1295,1, +1297,1, +1299,1, +1377,39, +7424,44, +7522,22, +7545,34, +7681,1, +7683,1, +7685,1, +7687,1, +7689,1, +7691,1, +7693,1, +7695,1, +7697,1, +7699,1, +7701,1, +7703,1, +7705,1, +7707,1, +7709,1, +7711,1, +7713,1, +7715,1, +7717,1, +7719,1, +7721,1, +7723,1, +7725,1, +7727,1, +7729,1, +7731,1, +7733,1, +7735,1, +7737,1, +7739,1, +7741,1, +7743,1, +7745,1, +7747,1, +7749,1, +7751,1, +7753,1, +7755,1, +7757,1, +7759,1, +7761,1, +7763,1, +7765,1, +7767,1, +7769,1, +7771,1, +7773,1, +7775,1, +7777,1, +7779,1, +7781,1, +7783,1, +7785,1, +7787,1, +7789,1, +7791,1, +7793,1, +7795,1, +7797,1, +7799,1, +7801,1, +7803,1, +7805,1, +7807,1, +7809,1, +7811,1, +7813,1, +7815,1, +7817,1, +7819,1, +7821,1, +7823,1, +7825,1, +7827,1, +7829,7, +7841,1, +7843,1, +7845,1, +7847,1, +7849,1, +7851,1, +7853,1, +7855,1, +7857,1, +7859,1, +7861,1, +7863,1, +7865,1, +7867,1, +7869,1, +7871,1, +7873,1, +7875,1, +7877,1, +7879,1, +7881,1, +7883,1, +7885,1, +7887,1, +7889,1, +7891,1, +7893,1, +7895,1, +7897,1, +7899,1, +7901,1, +7903,1, +7905,1, +7907,1, +7909,1, +7911,1, +7913,1, +7915,1, +7917,1, +7919,1, +7921,1, +7923,1, +7925,1, +7927,1, +7929,1, +7936,8, +7952,6, +7968,8, +7984,8, +8000,6, +8016,8, +8032,8, +8048,14, +8064,8, +8080,8, +8096,8, +8112,5, +8118,2, +8126,1, +8130,3, +8134,2, +8144,4, +8150,2, +8160,8, +8178,3, +8182,2, +8305,1, +8319,1, +8458,1, +8462,2, +8467,1, +8495,1, +8500,1, +8505,1, +8508,2, +8518,4, +8526,1, +8580,1, +11312,47, +11361,1, +11365,2, +11368,1, +11370,1, +11372,1, +11380,1, +11382,2, +11393,1, +11395,1, +11397,1, +11399,1, +11401,1, +11403,1, +11405,1, +11407,1, +11409,1, +11411,1, +11413,1, +11415,1, +11417,1, +11419,1, +11421,1, +11423,1, +11425,1, +11427,1, +11429,1, +11431,1, +11433,1, +11435,1, +11437,1, +11439,1, +11441,1, +11443,1, +11445,1, +11447,1, +11449,1, +11451,1, +11453,1, +11455,1, +11457,1, +11459,1, +11461,1, +11463,1, +11465,1, +11467,1, +11469,1, +11471,1, +11473,1, +11475,1, +11477,1, +11479,1, +11481,1, +11483,1, +11485,1, +11487,1, +11489,1, +11491,2, +11520,38, +64256,7, +64275,5, +65345,26, +66600,40, +119834,26, +119886,7, +119894,18, +119938,26, +119990,4, +119995,1, +119997,7, +120005,11, +120042,26, +120094,26, +120146,26, +120198,26, +120250,26, +120302,26, +120354,26, +120406,26, +120458,28, +120514,25, +120540,6, +120572,25, +120598,6, +120630,25, +120656,6, +120688,25, +120714,6, +120746,25, +120772,6, +120779,1}; +#else /* GNUSTEP_INDEX_CHARSET */ static const unsigned char lowercaseLetterCharSet[16384] = { '\x00', '\x00', @@ -565266,6 +567521,172 @@ static const unsigned char lowercaseLetterCharSet[16384] = { '\x00', '\x00', '\x00'}; +#endif /* GNUSTEP_INDEX_CHARSET */ +#if defined(GNUSTEP_INDEX_CHARSET) +static const unsigned int nonBaseCharSet[] = { +688,18, +710,12, +736,5, +750,1, +768,112, +890,1, +1155,4, +1160,2, +1369,1, +1425,45, +1471,1, +1473,2, +1476,2, +1479,1, +1552,6, +1600,1, +1611,20, +1648,1, +1750,7, +1758,11, +1770,4, +1809,1, +1840,27, +1958,11, +2027,11, +2042,1, +2305,3, +2364,1, +2366,16, +2385,4, +2402,2, +2433,3, +2492,1, +2494,7, +2503,2, +2507,3, +2519,1, +2530,2, +2561,3, +2620,1, +2622,5, +2631,2, +2635,3, +2672,2, +2689,3, +2748,1, +2750,8, +2759,3, +2763,3, +2786,2, +2817,3, +2876,1, +2878,6, +2887,2, +2891,3, +2902,2, +2946,1, +3006,5, +3014,3, +3018,4, +3031,1, +3073,3, +3134,7, +3142,3, +3146,4, +3157,2, +3202,2, +3260,1, +3262,7, +3270,3, +3274,4, +3285,2, +3298,2, +3330,2, +3390,6, +3398,3, +3402,4, +3415,1, +3458,2, +3530,1, +3535,6, +3542,1, +3544,8, +3570,2, +3633,1, +3636,7, +3654,9, +3761,1, +3764,6, +3771,2, +3782,1, +3784,6, +3864,2, +3893,1, +3895,1, +3897,1, +3902,2, +3953,20, +3974,2, +3984,8, +3993,36, +4038,1, +4140,7, +4150,4, +4182,4, +4348,1, +4959,1, +5906,3, +5938,3, +5970,2, +6002,2, +6070,30, +6103,1, +6109,1, +6155,3, +6211,1, +6313,1, +6432,12, +6448,12, +6576,17, +6600,2, +6679,5, +6912,5, +6964,17, +7019,9, +7468,54, +7544,1, +7579,48, +7678,2, +8336,5, +8400,32, +11631,1, +12293,1, +12330,6, +12337,5, +12347,1, +12441,2, +12445,2, +12540,3, +40981,1, +42775,4, +43010,1, +43014,1, +43019,1, +43043,5, +64286,1, +65024,16, +65056,4, +65392,1, +65438,2, +68097,3, +68101,2, +68108,4, +68152,3, +68159,1, +119141,5, +119149,6, +119163,8, +119173,7, +119210,4, +119362,3, +917760,240}; +#else /* GNUSTEP_INDEX_CHARSET */ static const unsigned char nonBaseCharSet[122880] = { '\x00', '\x00', @@ -688147,6 +690568,111 @@ static const unsigned char nonBaseCharSet[122880] = { '\x00', '\x00', '\x00'}; +#endif /* GNUSTEP_INDEX_CHARSET */ +#if defined(GNUSTEP_INDEX_CHARSET) +static const unsigned int punctuationCharSet[] = { +33,3, +37,6, +44,4, +58,2, +63,2, +91,3, +95,1, +123,1, +125,1, +161,1, +171,1, +183,1, +187,1, +191,1, +894,1, +903,1, +1370,6, +1417,2, +1470,1, +1472,1, +1475,1, +1478,1, +1523,2, +1548,2, +1563,1, +1566,2, +1642,4, +1748,1, +1792,14, +2039,3, +2404,2, +2416,1, +3572,1, +3663,1, +3674,2, +3844,15, +3898,4, +3973,1, +4048,2, +4170,6, +4347,1, +4961,8, +5741,2, +5787,2, +5867,3, +5941,2, +6100,3, +6104,3, +6144,11, +6468,2, +6622,2, +6686,2, +7002,7, +8208,24, +8240,20, +8261,13, +8275,12, +8317,2, +8333,2, +9001,2, +10088,14, +10181,2, +10214,6, +10627,22, +10712,4, +10748,2, +11513,4, +11518,2, +11776,24, +11804,2, +12289,3, +12296,10, +12308,12, +12336,1, +12349,1, +12448,1, +12539,1, +43124,4, +64830,2, +65040,10, +65072,35, +65108,14, +65123,1, +65128,1, +65130,2, +65281,3, +65285,6, +65292,4, +65306,2, +65311,2, +65339,3, +65343,1, +65371,1, +65373,1, +65375,7, +65792,2, +66463,1, +66512,1, +67871,1, +68176,9, +74864,4}; +#else /* GNUSTEP_INDEX_CHARSET */ static const unsigned char punctuationCharSet[16384] = { '\x00', '\x00', @@ -704532,6 +707058,176 @@ static const unsigned char punctuationCharSet[16384] = { '\x00', '\x00', '\x00'}; +#endif /* GNUSTEP_INDEX_CHARSET */ +#if defined(GNUSTEP_INDEX_CHARSET) +static const unsigned int symbolAndOperatorCharSet[] = { +36,1, +43,1, +60,3, +94,1, +96,1, +124,1, +126,1, +162,8, +172,1, +174,4, +180,1, +182,1, +184,1, +215,1, +247,1, +706,4, +722,14, +741,9, +751,17, +884,2, +900,2, +1014,1, +1154,1, +1547,1, +1550,2, +1769,1, +1789,2, +2038,1, +2546,2, +2554,1, +2801,1, +2928,1, +3059,8, +3313,2, +3647,1, +3841,3, +3859,5, +3866,6, +3892,1, +3894,1, +3896,1, +4030,8, +4039,6, +4047,1, +4960,1, +5008,10, +6107,1, +6464,1, +6624,32, +7009,10, +7028,9, +8125,1, +8127,3, +8141,3, +8157,3, +8173,3, +8189,2, +8260,1, +8274,1, +8314,3, +8330,3, +8352,22, +8448,2, +8451,4, +8456,2, +8468,1, +8470,3, +8478,6, +8485,1, +8487,1, +8489,1, +8494,1, +8506,2, +8512,5, +8522,4, +8592,409, +9003,189, +9216,39, +9280,11, +9372,78, +9472,413, +9888,19, +9985,4, +9990,4, +9996,28, +10025,35, +10061,1, +10063,4, +10070,1, +10072,7, +10081,7, +10132,1, +10136,24, +10161,14, +10176,5, +10183,4, +10192,22, +10224,403, +10649,63, +10716,32, +10750,285, +11040,4, +11493,6, +11904,26, +11931,89, +12032,214, +12272,12, +12292,1, +12306,2, +12320,1, +12342,2, +12350,2, +12443,2, +12688,2, +12694,10, +12736,16, +12800,31, +12842,26, +12880,1, +12896,32, +12938,39, +12992,63, +13056,256, +19904,64, +42128,55, +42752,23, +42784,2, +43048,4, +64297,1, +65020,2, +65122,1, +65124,3, +65129,1, +65284,1, +65291,1, +65308,3, +65342,1, +65344,1, +65372,1, +65374,1, +65504,7, +65512,7, +65532,2, +65794,1, +65847,9, +65913,17, +118784,246, +119040,39, +119082,59, +119146,3, +119171,2, +119180,30, +119214,48, +119296,66, +119365,1, +119552,87, +120513,1, +120539,1, +120571,1, +120597,1, +120629,1, +120655,1, +120687,1, +120713,1, +120745,1, +120771,1}; +#else /* GNUSTEP_INDEX_CHARSET */ static const unsigned char symbolAndOperatorCharSet[16384] = { '\x00', '\x00', @@ -720917,6 +723613,20 @@ static const unsigned char symbolAndOperatorCharSet[16384] = { '\x00', '\x00', '\x00'}; +#endif /* GNUSTEP_INDEX_CHARSET */ +#if defined(GNUSTEP_INDEX_CHARSET) +static const unsigned int titlecaseLetterCharSet[] = { +453,1, +456,1, +459,1, +498,1, +8072,8, +8088,8, +8104,8, +8124,1, +8140,1, +8188,1}; +#else /* GNUSTEP_INDEX_CHARSET */ static const unsigned char titlecaseLetterCharSet[8192] = { '\x00', '\x00', @@ -729110,6 +731820,503 @@ static const unsigned char titlecaseLetterCharSet[8192] = { '\x00', '\x00', '\x00'}; +#endif /* GNUSTEP_INDEX_CHARSET */ +#if defined(GNUSTEP_INDEX_CHARSET) +static const unsigned int uppercaseLetterCharSet[] = { +65,26, +192,23, +216,7, +256,1, +258,1, +260,1, +262,1, +264,1, +266,1, +268,1, +270,1, +272,1, +274,1, +276,1, +278,1, +280,1, +282,1, +284,1, +286,1, +288,1, +290,1, +292,1, +294,1, +296,1, +298,1, +300,1, +302,1, +304,1, +306,1, +308,1, +310,1, +313,1, +315,1, +317,1, +319,1, +321,1, +323,1, +325,1, +327,1, +330,1, +332,1, +334,1, +336,1, +338,1, +340,1, +342,1, +344,1, +346,1, +348,1, +350,1, +352,1, +354,1, +356,1, +358,1, +360,1, +362,1, +364,1, +366,1, +368,1, +370,1, +372,1, +374,1, +376,2, +379,1, +381,1, +385,2, +388,1, +390,2, +393,3, +398,4, +403,2, +406,3, +412,2, +415,2, +418,1, +420,1, +422,2, +425,1, +428,1, +430,2, +433,3, +437,1, +439,2, +444,1, +452,1, +455,1, +458,1, +461,1, +463,1, +465,1, +467,1, +469,1, +471,1, +473,1, +475,1, +478,1, +480,1, +482,1, +484,1, +486,1, +488,1, +490,1, +492,1, +494,1, +497,1, +500,1, +502,3, +506,1, +508,1, +510,1, +512,1, +514,1, +516,1, +518,1, +520,1, +522,1, +524,1, +526,1, +528,1, +530,1, +532,1, +534,1, +536,1, +538,1, +540,1, +542,1, +544,1, +546,1, +548,1, +550,1, +552,1, +554,1, +556,1, +558,1, +560,1, +562,1, +570,2, +573,2, +577,1, +579,4, +584,1, +586,1, +588,1, +590,1, +902,1, +904,3, +908,1, +910,2, +913,17, +931,9, +978,3, +984,1, +986,1, +988,1, +990,1, +992,1, +994,1, +996,1, +998,1, +1000,1, +1002,1, +1004,1, +1006,1, +1012,1, +1015,1, +1017,2, +1021,51, +1120,1, +1122,1, +1124,1, +1126,1, +1128,1, +1130,1, +1132,1, +1134,1, +1136,1, +1138,1, +1140,1, +1142,1, +1144,1, +1146,1, +1148,1, +1150,1, +1152,1, +1162,1, +1164,1, +1166,1, +1168,1, +1170,1, +1172,1, +1174,1, +1176,1, +1178,1, +1180,1, +1182,1, +1184,1, +1186,1, +1188,1, +1190,1, +1192,1, +1194,1, +1196,1, +1198,1, +1200,1, +1202,1, +1204,1, +1206,1, +1208,1, +1210,1, +1212,1, +1214,1, +1216,2, +1219,1, +1221,1, +1223,1, +1225,1, +1227,1, +1229,1, +1232,1, +1234,1, +1236,1, +1238,1, +1240,1, +1242,1, +1244,1, +1246,1, +1248,1, +1250,1, +1252,1, +1254,1, +1256,1, +1258,1, +1260,1, +1262,1, +1264,1, +1266,1, +1268,1, +1270,1, +1272,1, +1274,1, +1276,1, +1278,1, +1280,1, +1282,1, +1284,1, +1286,1, +1288,1, +1290,1, +1292,1, +1294,1, +1296,1, +1298,1, +1329,38, +4256,38, +7680,1, +7682,1, +7684,1, +7686,1, +7688,1, +7690,1, +7692,1, +7694,1, +7696,1, +7698,1, +7700,1, +7702,1, +7704,1, +7706,1, +7708,1, +7710,1, +7712,1, +7714,1, +7716,1, +7718,1, +7720,1, +7722,1, +7724,1, +7726,1, +7728,1, +7730,1, +7732,1, +7734,1, +7736,1, +7738,1, +7740,1, +7742,1, +7744,1, +7746,1, +7748,1, +7750,1, +7752,1, +7754,1, +7756,1, +7758,1, +7760,1, +7762,1, +7764,1, +7766,1, +7768,1, +7770,1, +7772,1, +7774,1, +7776,1, +7778,1, +7780,1, +7782,1, +7784,1, +7786,1, +7788,1, +7790,1, +7792,1, +7794,1, +7796,1, +7798,1, +7800,1, +7802,1, +7804,1, +7806,1, +7808,1, +7810,1, +7812,1, +7814,1, +7816,1, +7818,1, +7820,1, +7822,1, +7824,1, +7826,1, +7828,1, +7840,1, +7842,1, +7844,1, +7846,1, +7848,1, +7850,1, +7852,1, +7854,1, +7856,1, +7858,1, +7860,1, +7862,1, +7864,1, +7866,1, +7868,1, +7870,1, +7872,1, +7874,1, +7876,1, +7878,1, +7880,1, +7882,1, +7884,1, +7886,1, +7888,1, +7890,1, +7892,1, +7894,1, +7896,1, +7898,1, +7900,1, +7902,1, +7904,1, +7906,1, +7908,1, +7910,1, +7912,1, +7914,1, +7916,1, +7918,1, +7920,1, +7922,1, +7924,1, +7926,1, +7928,1, +7944,8, +7960,6, +7976,8, +7992,8, +8008,6, +8025,1, +8027,1, +8029,1, +8031,1, +8040,8, +8120,4, +8136,4, +8152,4, +8168,5, +8184,4, +8450,1, +8455,1, +8459,3, +8464,3, +8469,1, +8473,5, +8484,1, +8486,1, +8488,1, +8490,4, +8496,4, +8510,2, +8517,1, +8579,1, +11264,47, +11360,1, +11362,3, +11367,1, +11369,1, +11371,1, +11381,1, +11392,1, +11394,1, +11396,1, +11398,1, +11400,1, +11402,1, +11404,1, +11406,1, +11408,1, +11410,1, +11412,1, +11414,1, +11416,1, +11418,1, +11420,1, +11422,1, +11424,1, +11426,1, +11428,1, +11430,1, +11432,1, +11434,1, +11436,1, +11438,1, +11440,1, +11442,1, +11444,1, +11446,1, +11448,1, +11450,1, +11452,1, +11454,1, +11456,1, +11458,1, +11460,1, +11462,1, +11464,1, +11466,1, +11468,1, +11470,1, +11472,1, +11474,1, +11476,1, +11478,1, +11480,1, +11482,1, +11484,1, +11486,1, +11488,1, +11490,1, +65313,26, +66560,40, +119808,26, +119860,26, +119912,26, +119964,1, +119966,2, +119970,1, +119973,2, +119977,4, +119982,8, +120016,26, +120068,2, +120071,4, +120077,8, +120086,7, +120120,2, +120123,4, +120128,5, +120134,1, +120138,7, +120172,26, +120224,26, +120276,26, +120328,26, +120380,26, +120432,26, +120488,25, +120546,25, +120604,25, +120662,25, +120720,25, +120778,1}; +#else /* GNUSTEP_INDEX_CHARSET */ static const unsigned char uppercaseLetterCharSet[16384] = { '\x00', '\x00', @@ -745495,6 +748702,22 @@ static const unsigned char uppercaseLetterCharSet[16384] = { '\x00', '\x00', '\x00'}; +#endif /* GNUSTEP_INDEX_CHARSET */ +#if defined(GNUSTEP_INDEX_CHARSET) +static const unsigned int whitespaceAndNlCharSet[] = { +9,2, +13,1, +32,1, +133,1, +160,1, +5760,1, +6158,1, +8192,11, +8232,2, +8239,1, +8287,1, +12288,1}; +#else /* GNUSTEP_INDEX_CHARSET */ static const unsigned char whitespaceAndNlCharSet[8192] = { '\x00', '\x26', @@ -753688,6 +756911,20 @@ static const unsigned char whitespaceAndNlCharSet[8192] = { '\x00', '\x00', '\x00'}; +#endif /* GNUSTEP_INDEX_CHARSET */ +#if defined(GNUSTEP_INDEX_CHARSET) +static const unsigned int whitespaceCharSet[] = { +9,1, +32,1, +160,1, +5760,1, +6158,1, +8192,11, +8232,2, +8239,1, +8287,1, +12288,1}; +#else /* GNUSTEP_INDEX_CHARSET */ static const unsigned char whitespaceCharSet[8192] = { '\x00', '\x02', @@ -761881,3 +765118,4 @@ static const unsigned char whitespaceCharSet[8192] = { '\x00', '\x00', '\x00'}; +#endif /* GNUSTEP_INDEX_CHARSET */ diff --git a/Source/NSClassDescription.m b/Source/NSClassDescription.m index c4d7d2e83..bcbe50d54 100644 --- a/Source/NSClassDescription.m +++ b/Source/NSClassDescription.m @@ -18,7 +18,8 @@ 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., 51 Franklin Street, Fifth Floor, Boston, MA 02111 USA. + Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02111 USA. NSClassDescription class reference $Date$ $Revision$ diff --git a/Source/NSCoder.m b/Source/NSCoder.m index ef49c62af..15118027d 100644 --- a/Source/NSCoder.m +++ b/Source/NSCoder.m @@ -19,7 +19,8 @@ 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., 51 Franklin Street, Fifth Floor, Boston, MA 02111 USA. + Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02111 USA. NSCoder class reference $Date$ $Revision$ @@ -410,105 +411,6 @@ @end -@implementation NSCoder (GNUstep) -- (void) decodeArrayOfObjCType: (const char*)type - count: (unsigned)count - at: (void*)buf - withName: (id*)name -{ - GSOnceMLog(@"Deprecated, use NSKeyedArchiver methods"); - if (name) - { - *name = [self decodeObject]; - } - else - { - (void)[self decodeObject]; - } - [self decodeArrayOfObjCType: type count: count at: buf]; -} - -/** - */ -- (void) decodeIndent -{ - GSOnceMLog(@"Deprecated, use NSKeyedArchiver methods"); -} - -- (void) decodeObjectAt: (id*)anObject - withName: (id*)name -{ - GSOnceMLog(@"Deprecated, use NSKeyedArchiver methods"); - [self decodeValueOfObjCType: @encode(id) at: anObject withName: name]; -} - -- (void) decodeValueOfCType: (const char*)type - at: (void*)buf - withName: (id*)name -{ - GSOnceMLog(@"Deprecated, use NSKeyedArchiver methods"); - [self decodeValueOfObjCType: type at: buf withName: name]; -} - -- (void) decodeValueOfObjCType: (const char*)type - at: (void*)buf - withName: (id*)name -{ - GSOnceMLog(@"Deprecated, use NSKeyedArchiver methods"); - if (name != 0) - { - *name = [self decodeObject]; - } - else - { - (void)[self decodeObject]; - } - [self decodeValueOfObjCType: type at: buf]; -} - -- (void) encodeArrayOfObjCType: (const char*)type - count: (unsigned)count - at: (const void*)buf - withName: (id)name -{ - GSOnceMLog(@"Deprecated, use NSKeyedArchiver methods"); - [self encodeObject: name]; - [self encodeArrayOfObjCType: type count: count at: buf]; -} - -/** - */ -- (void) encodeIndent -{ - GSOnceMLog(@"Deprecated, use NSKeyedArchiver methods"); -} - -- (void) encodeValueOfCType: (const char*)type - at: (const void*)buf - withName: (id)name -{ - GSOnceMLog(@"Deprecated, use NSKeyedArchiver methods"); - [self encodeValueOfObjCType: type at: buf withName: name]; -} - -- (void) encodeValueOfObjCType: (const char*)type - at: (const void*)buf - withName: (id)name -{ - GSOnceMLog(@"Deprecated, use NSKeyedArchiver methods"); - [self encodeObject: name]; - [self encodeValueOfObjCType: type at: buf]; -} - -- (void) encodeObjectAt: (id*)anObject - withName: (id)name -{ - GSOnceMLog(@"Deprecated, use NSKeyedArchiver methods"); - [self encodeValueOfObjCType: @encode(id) at: anObject withName: name]; -} - -@end - #include "GSPrivate.h" diff --git a/Source/NSConcreteNumber.h b/Source/NSConcreteNumber.h index 83318bebc..5fa4ddad9 100644 --- a/Source/NSConcreteNumber.h +++ b/Source/NSConcreteNumber.h @@ -19,7 +19,8 @@ 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., 51 Franklin Street, Fifth Floor, Boston, MA 02111 USA. + Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02111 USA. */ #include diff --git a/Source/NSConcreteNumber.m b/Source/NSConcreteNumber.m index 38818869b..5e2f2e381 100644 --- a/Source/NSConcreteNumber.m +++ b/Source/NSConcreteNumber.m @@ -18,17 +18,19 @@ 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., 51 Franklin Street, Fifth Floor, Boston, MA 02111 USA. + Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02111 USA. */ #include "config.h" #include "GNUstepBase/preface.h" -#include "GSConfig.h" +#include "GNUstepBase/GSConfig.h" #include "Foundation/NSObjCRuntime.h" #include "Foundation/NSString.h" #include "Foundation/NSException.h" #include "Foundation/NSCoder.h" #include "NSConcreteNumber.h" +#include "GSPrivate.h" #define TYPE_ORDER 0 #include "NSConcreteNumberTemplate.m" diff --git a/Source/NSConcreteNumberTemplate.m b/Source/NSConcreteNumberTemplate.m index 49e08933e..3f08ba184 100644 --- a/Source/NSConcreteNumberTemplate.m +++ b/Source/NSConcreteNumberTemplate.m @@ -22,7 +22,8 @@ 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., 51 Franklin Street, Fifth Floor, Boston, MA 02111 USA. + Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02111 USA. */ /* This file should be run through a preprocessor with the macro TYPE_ORDER @@ -103,7 +104,7 @@ if (data <= GS_SMALL) #endif { - return GSSmallHash((int)data); + return GSPrivateSmallHash((int)data); } #endif diff --git a/Source/NSCopyObject.m b/Source/NSCopyObject.m index 331c371ee..190dcfc25 100644 --- a/Source/NSCopyObject.m +++ b/Source/NSCopyObject.m @@ -18,7 +18,8 @@ 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., 51 Franklin Street, Fifth Floor, Boston, MA 02111 USA. + Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02111 USA. NSCopyObject class reference $Date$ $Revision$ diff --git a/Source/NSCountedSet.m b/Source/NSCountedSet.m index 04ae4f170..61bcd9186 100644 --- a/Source/NSCountedSet.m +++ b/Source/NSCountedSet.m @@ -18,7 +18,8 @@ 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., 51 Franklin Street, Fifth Floor, Boston, MA 02111 USA. + Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02111 USA. NSCountedSet class reference $Date$ $Revision$ diff --git a/Source/NSData.m b/Source/NSData.m index 5de22d4fe..3b39f0d61 100644 --- a/Source/NSData.m +++ b/Source/NSData.m @@ -80,6 +80,7 @@ #include "Foundation/NSRange.h" #include "Foundation/NSURL.h" #include "Foundation/NSZone.h" +#include "GSPrivate.h" #include #include /* for memset() */ #ifdef HAVE_UNISTD_H @@ -163,8 +164,7 @@ readContentsOfFile(NSString* path, void** buf, unsigned int* len, NSZone* zone) if (theFile == 0) /* We failed to open the file. */ { - NSWarnFLog(@"Open (%@) attempt failed - %s", path, - GSLastErrorStr(errno)); + NSWarnFLog(@"Open (%@) attempt failed - %@", path, [NSError _last]); goto failure; } @@ -174,8 +174,8 @@ readContentsOfFile(NSString* path, void** buf, unsigned int* len, NSZone* zone) c = fseek(theFile, 0L, SEEK_END); if (c != 0) { - NSWarnFLog(@"Seek to end of file (%@) failed - %s", path, - GSLastErrorStr(errno)); + NSWarnFLog(@"Seek to end of file (%@) failed - %@", path, + [NSError _last]); goto failure; } @@ -186,8 +186,7 @@ readContentsOfFile(NSString* path, void** buf, unsigned int* len, NSZone* zone) fileLength = ftell(theFile); if (fileLength == -1) { - NSWarnFLog(@"Ftell on %@ failed - %s", path, - GSLastErrorStr(errno)); + NSWarnFLog(@"Ftell on %@ failed - %@", path, [NSError _last]); goto failure; } @@ -198,8 +197,8 @@ readContentsOfFile(NSString* path, void** buf, unsigned int* len, NSZone* zone) c = fseek(theFile, 0L, SEEK_SET); if (c != 0) { - NSWarnFLog(@"Fseek to start of file (%@) failed - %s", path, - GSLastErrorStr(errno)); + NSWarnFLog(@"Fseek to start of file (%@) failed - %@", path, + [NSError _last]); goto failure; } @@ -224,8 +223,8 @@ readContentsOfFile(NSString* path, void** buf, unsigned int* len, NSZone* zone) } if (tmp == 0) { - NSLog(@"Malloc failed for file (%@) of length %d - %s", path, - fileLength + c, GSLastErrorStr(errno)); + NSLog(@"Malloc failed for file (%@) of length %d - %@", path, + fileLength + c, [NSError _last]); goto failure; } memcpy(tmp + fileLength, buf, c); @@ -237,16 +236,16 @@ readContentsOfFile(NSString* path, void** buf, unsigned int* len, NSZone* zone) tmp = NSZoneMalloc(zone, fileLength); if (tmp == 0) { - NSLog(@"Malloc failed for file (%@) of length %d - %s", path, - fileLength, GSLastErrorStr(errno)); + NSLog(@"Malloc failed for file (%@) of length %d - %@", path, + fileLength, [NSError _last]); goto failure; } c = fread(tmp, 1, fileLength, theFile); if (c != (int)fileLength) { - NSWarnFLog(@"read of file (%@) contents failed - %s", path, - GSLastErrorStr(errno)); + NSWarnFLog(@"read of file (%@) contents failed - %@", path, + [NSError _last]); goto failure; } } @@ -852,8 +851,7 @@ failure: strcat(thePath, "XXXXXX"); if ((desc = mkstemp(thePath)) < 0) { - NSWarnMLog(@"mkstemp (%s) failed - %s", thePath, - GSLastErrorStr(errno)); + NSWarnMLog(@"mkstemp (%s) failed - %@", thePath, [NSError _last]); goto failure; } mask = umask(0); @@ -880,9 +878,9 @@ failure: wcscat(wthePath, L"XXXXXX"); if (_wmktemp(wthePath) == 0) { - NSWarnMLog(@"mktemp (%@) failed - %s", - [NSString stringWithCharacters:wthePath length:wcslen(wthePath)], - GSLastErrorStr(errno)); + NSWarnMLog(@"mktemp (%@) failed - %@", + [NSString stringWithCharacters: wthePath length: wcslen(wthePath)], + [NSError _last]); goto failure; } #else @@ -890,8 +888,7 @@ failure: strcat(thePath, "XXXXXX"); if (mktemp(thePath) == 0) { - NSWarnMLog(@"mktemp (%s) failed - %s", thePath, - GSLastErrorStr(errno)); + NSWarnMLog(@"mktemp (%s) failed - %@", thePath, [NSError _last]); goto failure; } #endif @@ -918,11 +915,11 @@ failure: /* Something went wrong; we weren't * even able to open the file. */ #if defined(__MINGW32__) - NSWarnMLog(@"Open (%@) failed - %s", + NSWarnMLog(@"Open (%@) failed - %@", [NSString stringWithCharacters: wthePath length: wcslen(wthePath)], - GSLastErrorStr(errno)); + [NSError _last]); #else - NSWarnMLog(@"Open (%s) failed - %s", thePath, GSLastErrorStr(errno)); + NSWarnMLog(@"Open (%s) failed - %@", thePath, [NSError _last]); #endif goto failure; } @@ -936,11 +933,11 @@ failure: * some reason. */ { #if defined(__MINGW32__) - NSWarnMLog(@"Fwrite (%@) failed - %s", - [NSString stringWithCharacters:wthePath length:wcslen(wthePath)], - GSLastErrorStr(errno)); + NSWarnMLog(@"Fwrite (%@) failed - %@", + [NSString stringWithCharacters: wthePath length: wcslen(wthePath)], + [NSError _last]); #else - NSWarnMLog(@"Fwrite (%s) failed - %s", thePath, GSLastErrorStr(errno)); + NSWarnMLog(@"Fwrite (%s) failed - %@", thePath, [NSError _last]); #endif goto failure; } @@ -953,11 +950,11 @@ failure: * so we need to deal with it. */ { #if defined(__MINGW32__) - NSWarnMLog(@"Fclose (%@) failed - %s", - [NSString stringWithCharacters:wthePath length:wcslen(wthePath)], - GSLastErrorStr(errno)); + NSWarnMLog(@"Fclose (%@) failed - %@", + [NSString stringWithCharacters: wthePath length: wcslen(wthePath)], + [NSError _last]); #else - NSWarnMLog(@"Fclose (%s) failed - %s", thePath, GSLastErrorStr(errno)); + NSWarnMLog(@"Fclose (%s) failed - %@", thePath, [NSError _last]); #endif goto failure; } @@ -1038,14 +1035,15 @@ failure: if (c != 0) /* Many things could go wrong, I guess. */ { #if defined(__MINGW32__) - NSWarnMLog(@"Rename ('%@' to '%@') failed - %s", - [NSString stringWithCharacters: wthePath length:wcslen(wthePath)], - [NSString stringWithCharacters: - wtheRealPath length:wcslen(wtheRealPath)], - GSLastErrorStr(errno)); + NSWarnMLog(@"Rename ('%@' to '%@') failed - %@", + [NSString stringWithCharacters: wthePath + length: wcslen(wthePath)], + [NSString stringWithCharacters: wtheRealPath + length: wcslen(wtheRealPath)], + [NSError _last]); #else - NSWarnMLog(@"Rename ('%s' to '%s') failed - %s", - thePath, theRealPath, GSLastErrorStr(errno)); + NSWarnMLog(@"Rename ('%s' to '%s') failed - %@", + thePath, theRealPath, [NSError _last]); #endif goto failure; } @@ -2918,7 +2916,7 @@ getBytes(void* dst, void* src, unsigned len, unsigned limit, unsigned *pos) #endif if (fd < 0) { - NSWarnMLog(@"unable to open %@ - %s", path, GSLastErrorStr(errno)); + NSWarnMLog(@"unable to open %@ - %@", path, [NSError _last]); RELEASE(self); return nil; } @@ -2926,7 +2924,7 @@ getBytes(void* dst, void* src, unsigned len, unsigned limit, unsigned *pos) length = lseek(fd, 0, SEEK_END); if (length < 0) { - NSWarnMLog(@"unable to seek to eof %@ - %s", path, GSLastErrorStr(errno)); + NSWarnMLog(@"unable to seek to eof %@ - %@", path, [NSError _last]); close(fd); RELEASE(self); return nil; @@ -2934,7 +2932,7 @@ getBytes(void* dst, void* src, unsigned len, unsigned limit, unsigned *pos) /* Position at start of file. */ if (lseek(fd, 0, SEEK_SET) != 0) { - NSWarnMLog(@"unable to seek to sof %@ - %s", path, GSLastErrorStr(errno)); + NSWarnMLog(@"unable to seek to sof %@ - %@", path, [NSError _last]); close(fd); RELEASE(self); return nil; @@ -2942,7 +2940,7 @@ getBytes(void* dst, void* src, unsigned len, unsigned limit, unsigned *pos) bytes = mmap(0, length, PROT_READ, MAP_SHARED, fd, 0); if (bytes == MAP_FAILED) { - NSWarnMLog(@"mapping failed for %s - %s", path, GSLastErrorStr(errno)); + NSWarnMLog(@"mapping failed for %s - %@", path, [NSError _last]); close(fd); RELEASE(self); self = [dataMalloc allocWithZone: NSDefaultMallocZone()]; @@ -2969,15 +2967,15 @@ getBytes(void* dst, void* src, unsigned len, unsigned limit, unsigned *pos) struct shmid_ds buf; if (shmctl(shmid, IPC_STAT, &buf) < 0) - NSLog(@"[NSDataShared -dealloc] shared memory control failed - %s", - GSLastErrorStr(errno)); + NSLog(@"[NSDataShared -dealloc] shared memory control failed - %@", + [NSError _last]); else if (buf.shm_nattch == 1) if (shmctl(shmid, IPC_RMID, &buf) < 0) /* Mark for deletion. */ - NSLog(@"[NSDataShared -dealloc] shared memory delete failed - %s", - GSLastErrorStr(errno)); + NSLog(@"[NSDataShared -dealloc] shared memory delete failed - %@", + [NSError _last]); if (shmdt(bytes) < 0) - NSLog(@"[NSDataShared -dealloc] shared memory detach failed - %s", - GSLastErrorStr(errno)); + NSLog(@"[NSDataShared -dealloc] shared memory detach failed - %@", + [NSError _last]); bytes = 0; length = 0; shmid = -1; @@ -2993,8 +2991,8 @@ getBytes(void* dst, void* src, unsigned len, unsigned limit, unsigned *pos) shmid = shmget(IPC_PRIVATE, bufferSize, IPC_CREAT|VM_RDONLY); if (shmid == -1) /* Created memory? */ { - NSLog(@"[-initWithBytes:length:] shared mem get failed for %u - %s", - bufferSize, GSLastErrorStr(errno)); + NSLog(@"[-initWithBytes:length:] shared mem get failed for %u - %@", + bufferSize, [NSError _last]); RELEASE(self); self = [dataMalloc allocWithZone: NSDefaultMallocZone()]; return [self initWithBytes: aBuffer length: bufferSize]; @@ -3003,8 +3001,8 @@ getBytes(void* dst, void* src, unsigned len, unsigned limit, unsigned *pos) bytes = shmat(shmid, 0, 0); if (bytes == (void*)-1) { - NSLog(@"[-initWithBytes:length:] shared mem attach failed for %u - %s", - bufferSize, GSLastErrorStr(errno)); + NSLog(@"[-initWithBytes:length:] shared mem attach failed for %u - %@", + bufferSize, [NSError _last]); bytes = 0; RELEASE(self); self = [dataMalloc allocWithZone: NSDefaultMallocZone()]; @@ -3022,21 +3020,23 @@ getBytes(void* dst, void* src, unsigned len, unsigned limit, unsigned *pos) shmid = anId; if (shmctl(shmid, IPC_STAT, &buf) < 0) { - NSLog(@"[NSDataShared -initWithShmID:length:] shared memory control failed - %s", GSLastErrorStr(errno)); + NSLog(@"[NSDataShared -initWithShmID:length:] shared memory " + @"control failed - %@", [NSError _last]); RELEASE(self); /* Unable to access memory. */ return nil; } if (buf.shm_segsz < bufferSize) { - NSLog(@"[NSDataShared -initWithShmID:length:] shared memory segment too small"); + NSLog(@"[NSDataShared -initWithShmID:length:] shared memory " + @"segment too small"); RELEASE(self); /* Memory segment too small. */ return nil; } bytes = shmat(shmid, 0, 0); if (bytes == (void*)-1) { - NSLog(@"[NSDataShared -initWithShmID:length:] shared memory attach failed - %s", - GSLastErrorStr(errno)); + NSLog(@"[NSDataShared -initWithShmID:length:] shared memory " + @"attach failed - %s", [NSError _last]); bytes = 0; RELEASE(self); /* Unable to attach to memory. */ return nil; @@ -3162,7 +3162,7 @@ getBytes(void* dst, void* src, unsigned len, unsigned limit, unsigned *pos) if (bytes == 0) { NSLog(@"[NSMutableDataMalloc -initWithCapacity:] out of memory " - @"for %u bytes - %s", size, GSLastErrorStr(errno)); + @"for %u bytes - %@", size, [NSError _last]); RELEASE(self); return nil; } @@ -3658,20 +3658,20 @@ getBytes(void* dst, void* src, unsigned len, unsigned limit, unsigned *pos) if (shmctl(shmid, IPC_STAT, &buf) < 0) { NSLog(@"[NSMutableDataShared -dealloc] shared memory " - @"control failed - %s", GSLastErrorStr(errno)); + @"control failed - %@", [NSError _last]); } else if (buf.shm_nattch == 1) { if (shmctl(shmid, IPC_RMID, &buf) < 0) /* Mark for deletion. */ { NSLog(@"[NSMutableDataShared -dealloc] shared memory " - @"delete failed - %s", GSLastErrorStr(errno)); + @"delete failed - %@", [NSError _last]); } } if (shmdt(bytes) < 0) { NSLog(@"[NSMutableDataShared -dealloc] shared memory " - @"detach failed - %s", GSLastErrorStr(errno)); + @"detach failed - %@", [NSError _last]); } bytes = 0; length = 0; @@ -3695,24 +3695,21 @@ getBytes(void* dst, void* src, unsigned len, unsigned limit, unsigned *pos) - (id) initWithCapacity: (unsigned int)bufferSize { - int e; - shmid = shmget(IPC_PRIVATE, bufferSize, IPC_CREAT|VM_ACCESS); if (shmid == -1) /* Created memory? */ { NSLog(@"[NSMutableDataShared -initWithCapacity:] shared memory " - @"get failed for %u - %s", bufferSize, GSLastErrorStr(errno)); + @"get failed for %u - %@", bufferSize, [NSError _last]); RELEASE(self); self = [mutableDataMalloc allocWithZone: NSDefaultMallocZone()]; return [self initWithCapacity: bufferSize]; } bytes = shmat(shmid, 0, 0); - e = errno; if (bytes == (void*)-1) { NSLog(@"[NSMutableDataShared -initWithCapacity:] shared memory " - @"attach failed for %u - %s", bufferSize, GSLastErrorStr(e)); + @"attach failed for %u - %@", bufferSize, [NSError _last]); bytes = 0; RELEASE(self); self = [mutableDataMalloc allocWithZone: NSDefaultMallocZone()]; @@ -3732,7 +3729,7 @@ getBytes(void* dst, void* src, unsigned len, unsigned limit, unsigned *pos) if (shmctl(shmid, IPC_STAT, &buf) < 0) { NSLog(@"[NSMutableDataShared -initWithShmID:length:] shared memory " - @"control failed - %s", GSLastErrorStr(errno)); + @"control failed - %@", [NSError _last]); RELEASE(self); /* Unable to access memory. */ return nil; } @@ -3747,7 +3744,7 @@ getBytes(void* dst, void* src, unsigned len, unsigned limit, unsigned *pos) if (bytes == (void*)-1) { NSLog(@"[NSMutableDataShared -initWithShmID:length:] shared memory " - @"attach failed - %s", GSLastErrorStr(errno)); + @"attach failed - %@", [NSError _last]); bytes = 0; RELEASE(self); /* Unable to attach to memory. */ return nil; @@ -3769,8 +3766,8 @@ getBytes(void* dst, void* src, unsigned len, unsigned limit, unsigned *pos) if (newid == -1) /* Created memory? */ { [NSException raise: NSMallocException - format: @"Unable to create shared memory segment (size:%u) - %s.", - size, GSLastErrorStr(errno)]; + format: @"Unable to create shared memory segment (size:%u) - %@.", + size, [NSError _last]]; } tmp = shmat(newid, 0, 0); if ((intptr_t)tmp == -1) /* Attached memory? */ @@ -3786,20 +3783,20 @@ getBytes(void* dst, void* src, unsigned len, unsigned limit, unsigned *pos) if (shmctl(shmid, IPC_STAT, &buf) < 0) { NSLog(@"[NSMutableDataShared -setCapacity:] shared memory " - @"control failed - %s", GSLastErrorStr(errno)); + @"control failed - %@", [NSError _last]); } else if (buf.shm_nattch == 1) { if (shmctl(shmid, IPC_RMID, &buf) < 0) /* Mark for deletion. */ { NSLog(@"[NSMutableDataShared -setCapacity:] shared memory " - @"delete failed - %s", GSLastErrorStr(errno)); + @"delete failed - %@", [NSError _last]); } } if (shmdt(bytes) < 0) /* Detach memory. */ { NSLog(@"[NSMutableDataShared -setCapacity:] shared memory " - @"detach failed - %s", GSLastErrorStr(errno)); + @"detach failed - %@", [NSError _last]); } } bytes = tmp; diff --git a/Source/NSDate.m b/Source/NSDate.m index 219a7d1d1..991d081a3 100644 --- a/Source/NSDate.m +++ b/Source/NSDate.m @@ -29,17 +29,17 @@ #include "config.h" #include "Foundation/NSArray.h" -#include "Foundation/NSDictionary.h" -#include "Foundation/NSDate.h" #include "Foundation/NSCalendarDate.h" -#include "Foundation/NSTimeZone.h" -#include "Foundation/NSString.h" -#include "Foundation/NSCoder.h" -#include "Foundation/NSException.h" #include "Foundation/NSCharacterSet.h" -#include "Foundation/NSScanner.h" +#include "Foundation/NSCoder.h" +#include "Foundation/NSDate.h" +#include "Foundation/NSDictionary.h" +#include "Foundation/NSException.h" #include "Foundation/NSObjCRuntime.h" #include "Foundation/NSPortCoder.h" +#include "Foundation/NSScanner.h" +#include "Foundation/NSString.h" +#include "Foundation/NSTimeZone.h" #include "Foundation/NSUserDefaults.h" #include "GNUstepBase/preface.h" #include "GNUstepBase/GSObjCRuntime.h" @@ -264,7 +264,7 @@ otherTime(NSDate* other) if (locale == nil) { - locale = GSUserDefaultsDictionaryRepresentation(); + locale = GSPrivateDefaultLocale(); } ws = [NSCharacterSet whitespaceAndNewlineCharacterSet]; digits = [NSCharacterSet decimalDigitCharacterSet]; diff --git a/Source/NSDateFormatter.m b/Source/NSDateFormatter.m index 4731978fb..8ac6c54de 100644 --- a/Source/NSDateFormatter.m +++ b/Source/NSDateFormatter.m @@ -18,7 +18,8 @@ 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., 51 Franklin Street, Fifth Floor, Boston, MA 02111 USA. + Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02111 USA. NSDateFormatter class reference $Date$ $Revision$ @@ -81,7 +82,14 @@ { NSCalendarDate *d; - d = [NSCalendarDate dateWithString: string calendarFormat: _dateFormat]; + if ([string length] == 0) + { + d = nil; + } + else + { + d = [NSCalendarDate dateWithString: string calendarFormat: _dateFormat]; + } if (d == nil) { if (_allowsNaturalLanguage) diff --git a/Source/NSDecimal.m b/Source/NSDecimal.m index fbac74d23..464c4c823 100644 --- a/Source/NSDecimal.m +++ b/Source/NSDecimal.m @@ -19,7 +19,8 @@ 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., 51 Franklin Street, Fifth Floor, Boston, MA 02111 USA. + Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02111 USA. NSDecimal class reference $Date$ $Revision$ @@ -236,7 +237,7 @@ GSDecimalCompare(const GSDecimal *leftOperand, const GSDecimal *rightOperand) static NSComparisonResult NSSimpleCompare(const NSDecimal *leftOperand, const NSDecimal *rightOperand); -void +static void GSDecimalRound(GSDecimal *result, int scale, NSRoundingMode mode) { int i; @@ -332,7 +333,7 @@ GSDecimalRound(GSDecimal *result, int scale, NSRoundingMode mode) GSDecimalCompact(result); } -NSCalculationError +static NSCalculationError GSDecimalNormalize(GSDecimal *n1, GSDecimal *n2, NSRoundingMode mode) { // Both are valid numbers and the exponents are not equal @@ -673,7 +674,7 @@ NSDecimalMultiply(NSDecimal *result, const NSDecimal *l, const NSDecimal *r, return error; } -NSCalculationError +static NSCalculationError GSSimpleDivide(NSDecimal *result, const NSDecimal *l, const NSDecimal *r, NSRoundingMode mode); @@ -796,7 +797,7 @@ NSDecimalMultiplyByPowerOf10(NSDecimal *result, const NSDecimal *n, short power, return NSCalculationNoError; } -NSString* +static NSString* GSDecimalString(const GSDecimal *number, NSDictionary *locale) { int i; @@ -902,7 +903,7 @@ NSDecimalMin(NSDecimal *result) } // Give back the value of a NSDecimal as a double -double +static double GSDecimalDouble(GSDecimal *number) { double d = 0.0; @@ -931,7 +932,7 @@ GSDecimalDouble(GSDecimal *number) // Create a NSDecimal with a cMantissa, exponent and a negative flag -void +static void GSDecimalFromComponents(GSDecimal *result, unsigned long long mantissa, short exponent, BOOL negative) { @@ -963,7 +964,7 @@ GSDecimalFromComponents(GSDecimal *result, unsigned long long mantissa, } // Create a NSDecimal from a string using the local -void +static void GSDecimalFromString(GSDecimal *result, NSString *numberValue, NSDictionary *locale) { @@ -1157,7 +1158,7 @@ NSDecimalNormalize(NSDecimal *n1, NSDecimal *n2, NSRoundingMode mode) */ } -NSCalculationError +static NSCalculationError GSSimpleAdd(NSDecimal *result, const NSDecimal *left, const NSDecimal *right, NSRoundingMode mode) { @@ -1235,7 +1236,7 @@ GSSimpleMultiply(NSDecimal *result, NSDecimal *left, NSDecimal *right, NSRoundin return error; } -NSCalculationError +static NSCalculationError GSSimpleDivide(NSDecimal *result, const NSDecimal *left, const NSDecimal *right, NSRoundingMode mode) { @@ -1535,7 +1536,7 @@ GSSimpleMultiply(NSDecimal *result, NSDecimal *l, NSDecimal *r, NSRoundingMode m return error; } -NSCalculationError +static NSCalculationError GSSimpleDivide(NSDecimal *result, const NSDecimal *l, const NSDecimal *r, NSRoundingMode mode) { diff --git a/Source/NSDecimalNumber.m b/Source/NSDecimalNumber.m index 2f99e2d77..f7462ce5a 100644 --- a/Source/NSDecimalNumber.m +++ b/Source/NSDecimalNumber.m @@ -239,8 +239,7 @@ static NSDecimalNumber *one; NSString *s; memcpy(&tmp, value, sizeof(tmp)); - s = [[NSString alloc] initWithFormat: @"%g" - locale: GSUserDefaultsDictionaryRepresentation(), tmp]; + s = [[NSString alloc] initWithFormat: @"%g", tmp]; self = [self initWithString: s]; RELEASE(s); return self; @@ -265,7 +264,7 @@ static NSDecimalNumber *one; - (id) initWithString: (NSString*)numberValue { return [self initWithString: numberValue - locale: GSUserDefaultsDictionaryRepresentation()]; + locale: GSPrivateDefaultLocale()]; } - (id) initWithString: (NSString*)numberValue diff --git a/Source/NSDictionary.m b/Source/NSDictionary.m index 3315f1334..2d82c28c0 100644 --- a/Source/NSDictionary.m +++ b/Source/NSDictionary.m @@ -40,11 +40,23 @@ #include "Foundation/NSObjCRuntime.h" #include "Foundation/NSValue.h" #include "Foundation/NSKeyValueCoding.h" +#include "Foundation/NSUserDefaults.h" // For private method _decodeArrayOfObjectsForKey: #include "Foundation/NSKeyedArchiver.h" #include "GNUstepBase/GSCategories.h" #include "GSPrivate.h" +static BOOL GSMacOSXCompatiblePropertyLists(void) +{ +#if defined(HAVE_LIBXML) + if (GSPrivateDefaultsFlag(NSWriteOldStylePropertyLists) == YES) + return NO; + return GSPrivateDefaultsFlag(GSMacOSXCompatible); +#else + return NO; +#endif +} + @class GSDictionary; @interface GSDictionary : NSObject // Help the compiler @end @@ -52,7 +64,6 @@ @interface GSMutableDictionary : NSObject // Help the compiler @end -extern BOOL GSMacOSXCompatiblePropertyLists(void); extern void GSPropertyListMake(id,NSDictionary*,BOOL,BOOL,unsigned,id*); @@ -76,10 +87,11 @@ static SEL appSel; * retrieve multiple entries simultaneously, obtain sorted contents, and * read/write from/to a serialized representation.

* - *

Both keys and values are retained by the implementation, and released - * when either their entry is dropped or the entire dictionary is deallocated. - * This differs from the implementation on OS X, where keys are copied instead - * of being retained and must therefore implement the [(NSCopying)] protocol. + *

The keys are copied and values are retained by the implementation, + * and both are released when either their entry is dropped or the entire + * dictionary is deallocated.
+ * As in the OS X implementation, keys must therefore implement the + * [(NSCopying)] protocol. *

* *

Objects of this class are immutable. For a mutable version, use the @@ -496,7 +508,10 @@ static SEL appSel; /** * Initialise dictionary with the keys and values of otherDictionary. * If the shouldCopy flag is YES then the values are copied into the - * newly initialised dictionary, otherwise they are simply retained. + * newly initialised dictionary, otherwise they are simply retained, + * on the assumption that it is safe to retain the keys from another + * dictionary since that other dictionary mwill have copied the keys + * originally to ensure that they are immutable. */ - (id) initWithDictionary: (NSDictionary*)other copyItems: (BOOL)shouldCopy @@ -929,10 +944,11 @@ compareIt(id o1, id o2, void* context) */ - (BOOL) writeToFile: (NSString *)path atomically: (BOOL)useAuxiliaryFile { - NSDictionary *loc = GSUserDefaultsDictionaryRepresentation(); + NSDictionary *loc; NSString *desc = nil; NSData *data; + loc = [[NSUserDefaults standardUserDefaults] dictionaryRepresentation]; if (GSMacOSXCompatiblePropertyLists() == YES) { GSPropertyListMake(self, loc, YES, NO, 2, &desc); @@ -954,10 +970,11 @@ compareIt(id o1, id o2, void* context) */ - (BOOL) writeToURL: (NSURL *)url atomically: (BOOL)useAuxiliaryFile { - NSDictionary *loc = GSUserDefaultsDictionaryRepresentation(); + NSDictionary *loc; NSString *desc = nil; NSData *data; + loc = [[NSUserDefaults standardUserDefaults] dictionaryRepresentation]; if (GSMacOSXCompatiblePropertyLists() == YES) { GSPropertyListMake(self, loc, YES, NO, 2, &desc); @@ -1142,9 +1159,9 @@ compareIt(id o1, id o2, void* context) /** * Adds entry for aKey, mapping to anObject. If either is nil, an exception * is raised. If aKey already in dictionary, the value it maps to is - * silently replaced. aKey and anObject are both retained. (This differs - * from OS X, where the key is copied and must therefore implement the - * [(NSCopying)] protocol.) + * silently replaced. The value anObject is retained, but aKey is copied + * (because a dictionary key must be immutable) and must therefore implement + * the [(NSCopying)] protocol.) */ - (void) setObject: anObject forKey: (id)aKey { diff --git a/Source/NSDistantObject.m b/Source/NSDistantObject.m index 2062f7fb7..18d22e923 100644 --- a/Source/NSDistantObject.m +++ b/Source/NSDistantObject.m @@ -19,8 +19,8 @@ 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., 51 Franklin Street, Fifth Floor, Boston, - MA 02111 USA. + Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02111 USA. NSDistantObject class reference $Date$ $Revision$ diff --git a/Source/NSDistributedLock.m b/Source/NSDistributedLock.m index 004f2647a..d17e73e30 100644 --- a/Source/NSDistributedLock.m +++ b/Source/NSDistributedLock.m @@ -18,7 +18,8 @@ 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., 51 Franklin Street, Fifth Floor, Boston, MA 02111 USA. + Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02111 USA. NSDistributedLock class reference $Date$ $Revision$ @@ -31,6 +32,7 @@ #include "Foundation/NSException.h" #include "Foundation/NSValue.h" #include "Foundation/NSDebug.h" +#include "GSPrivate.h" #include @@ -76,13 +78,13 @@ static NSFileManager *mgr = nil; if ([mgr removeFileAtPath: _lockPath handler: nil] == NO) { - const char *err = GSLastErrorStr(errno); + NSString *err = [[NSError _last] localizedDescription]; attributes = [mgr fileAttributesAtPath: _lockPath traverseLink: YES]; if ([modDate isEqual: [attributes fileModificationDate]] == YES) { [NSException raise: NSGenericException - format: @"Failed to remove lock directory '%@' - %s", + format: @"Failed to remove lock directory '%@' - %@", _lockPath, err]; } } @@ -201,8 +203,8 @@ static NSFileManager *mgr = nil; attributes: attributesToSet]; if (locked == NO) { - NSLog(@"Failed to create lock directory '%@' - %s", - _lockPath, GSLastErrorStr(errno)); + NSLog(@"Failed to create lock directory '%@' - %@", + _lockPath, [NSError _last]); } } } @@ -257,8 +259,8 @@ static NSFileManager *mgr = nil; if ([mgr removeFileAtPath: _lockPath handler: nil] == NO) { [NSException raise: NSGenericException - format: @"Failed to remove lock directory '%@' - %s", - _lockPath, GSLastErrorStr(errno)]; + format: @"Failed to remove lock directory '%@' - %@", + _lockPath, [NSError _last]]; } } else diff --git a/Source/NSDistributedNotificationCenter.m b/Source/NSDistributedNotificationCenter.m index 1897e6662..5847c0dbd 100644 --- a/Source/NSDistributedNotificationCenter.m +++ b/Source/NSDistributedNotificationCenter.m @@ -710,17 +710,29 @@ static NSDistributedNotificationCenter *netCenter = nil; if (_type == GSNetworkNotificationCenterType) { args = [NSArray arrayWithObjects: - @"-GSNetwork", @"YES", nil]; + @"-GSNetwork", @"YES", + @"--auto", + nil]; } else if (_type == GSPublicNotificationCenterType) { args = [NSArray arrayWithObjects: - @"-GSPublic", @"YES", nil]; + @"-GSPublic", @"YES", + @"--auto", + nil]; } else if ([host length] > 0) { args = [NSArray arrayWithObjects: - @"-NSHost", host, nil]; + @"-NSHost", host, + @"--auto", + nil]; + } + else + { + args = [NSArray arrayWithObjects: + @"--auto", + nil]; } [NSTask launchedTaskWithLaunchPath: cmd arguments: args]; diff --git a/Source/NSEnumerator.m b/Source/NSEnumerator.m index 49b18d22c..88383db1d 100644 --- a/Source/NSEnumerator.m +++ b/Source/NSEnumerator.m @@ -18,7 +18,8 @@ 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., 51 Franklin Street, Fifth Floor, Boston, MA 02111 USA. + Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02111 USA. NSEnumerator class reference $Date$ $Revision$ diff --git a/Source/NSError.m b/Source/NSError.m index 67f3884bf..aa16b156d 100644 --- a/Source/NSError.m +++ b/Source/NSError.m @@ -18,7 +18,8 @@ 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., 51 Franklin Street, Fifth Floor, Boston, MA 02111 USA. + Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02111 USA. */ #include @@ -26,11 +27,25 @@ #include #include +NSString* const NSFilePathErrorKey = @"NSFilePathErrorKey"; NSString* const NSLocalizedDescriptionKey = @"NSLocalizedDescriptionKey"; +NSString* const NSStringEncodingErrorKey = @"NSStringEncodingErrorKey"; +NSString* const NSURLErrorKey = @"NSURLErrorKey"; NSString* const NSUnderlyingErrorKey = @"NSUnderlyingErrorKey"; + +NSString* const NSLocalizedFailureReasonErrorKey + = @"NSLocalizedFailureReasonErrorKey"; +NSString* const NSLocalizedRecoveryOptionsErrorKey + = @"NSLocalizedRecoveryOptionsErrorKey"; +NSString* const NSLocalizedRecoverySuggestionErrorKey + = @"NSLocalizedRecoverySuggestionErrorKey"; +NSString* const NSRecoveryAttempterErrorKey + = @"NSRecoveryAttempterErrorKey"; + NSString* const NSMACHErrorDomain = @"NSMACHErrorDomain"; NSString* const NSOSStatusErrorDomain = @"NSOSStatusErrorDomain"; NSString* const NSPOSIXErrorDomain = @"NSPOSIXErrorDomain"; +NSString* const NSCocoaErrorDomain = @"NSCocoaErrorDomain"; @implementation NSError @@ -64,6 +79,11 @@ NSString* const NSPOSIXErrorDomain = @"NSPOSIXErrorDomain"; [super dealloc]; } +- (NSString*) description +{ + return [self localizedDescription]; +} + - (NSString*) domain { return _domain; @@ -131,7 +151,7 @@ NSString* const NSPOSIXErrorDomain = @"NSPOSIXErrorDomain"; return self; } -- (NSString *)localizedDescription +- (NSString *) localizedDescription { NSString *desc = [_userInfo objectForKey: NSLocalizedDescriptionKey]; @@ -142,6 +162,26 @@ NSString* const NSPOSIXErrorDomain = @"NSPOSIXErrorDomain"; return desc; } +- (NSString *) localizedFailureReason +{ + return [_userInfo objectForKey: NSLocalizedFailureReasonErrorKey]; +} + +- (NSArray *) localizedRecoveryOptions +{ + return [_userInfo objectForKey: NSLocalizedRecoveryOptionsErrorKey]; +} + +- (NSString *) localizedRecoverySuggestion +{ + return [_userInfo objectForKey: NSLocalizedRecoverySuggestionErrorKey]; +} + +- (id) recoveryAttempter +{ + return [_userInfo objectForKey: NSRecoveryAttempterErrorKey]; +} + - (NSDictionary*) userInfo { return _userInfo; diff --git a/Source/NSException.m b/Source/NSException.m index 2c2b91b09..1054fdb2c 100644 --- a/Source/NSException.m +++ b/Source/NSException.m @@ -680,7 +680,7 @@ static void _terminate() #else shouldAbort = NO; // exit() by default. #endif - shouldAbort = GSEnvironmentFlag("CRASH_ON_ABORT", shouldAbort); + shouldAbort = GSPrivateEnvironmentFlag("CRASH_ON_ABORT", shouldAbort); if (shouldAbort == YES) { abort(); @@ -694,10 +694,10 @@ static void _terminate() static void _NSFoundationUncaughtExceptionHandler (NSException *exception) { - extern const char *GSArgZero(void); - NSString *stack; + NSString *stack; - fprintf(stderr, "%s: Uncaught exception %s, reason: %s\n", GSArgZero(), + fprintf(stderr, "%s: Uncaught exception %s, reason: %s\n", + GSPrivateArgZero(), [[exception name] lossyCString], [[exception reason] lossyCString]); fflush(stderr); /* NEEDED UNDER MINGW */ stack = [[[exception userInfo] objectForKey: @"GSStackTraceKey"] description]; @@ -779,7 +779,7 @@ _NSFoundationUncaughtExceptionHandler (NSException *exception) #endif #if defined(DEBUG) - if (GSEnvironmentFlag("GNUSTEP_STACK_TRACE", NO) == YES + if (GSPrivateEnvironmentFlag("GNUSTEP_STACK_TRACE", NO) == YES && [_e_info objectForKey: @"GSStackTraceKey"] == nil) { NSMutableDictionary *m; diff --git a/Source/NSFileHandle.m b/Source/NSFileHandle.m index a024ab497..862581181 100644 --- a/Source/NSFileHandle.m +++ b/Source/NSFileHandle.m @@ -18,7 +18,8 @@ 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., 51 Franklin Street, Fifth Floor, Boston, MA 02111 USA. + Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02111 USA. NSFileHandle class reference $Date$ $Revision$ @@ -709,13 +710,12 @@ NSString * const NSFileHandleOperationException { if (NSFileHandle_ssl_class == 0) { + NSString *path; NSBundle *bundle; - NSString *path; - path = [NSSearchPathForDirectoriesInDomains(NSLibraryDirectory, - NSSystemDomainMask, NO) lastObject]; - path = [path stringByAppendingPathComponent: @"Bundles"]; + path = [[NSBundle bundleForClass: [NSObject class]] bundlePath]; path = [path stringByAppendingPathComponent: @"SSL.bundle"]; + bundle = [NSBundle bundleWithPath: path]; NSFileHandle_ssl_class = [bundle principalClass]; if (NSFileHandle_ssl_class == 0 && bundle != nil) diff --git a/Source/NSFileManager.m b/Source/NSFileManager.m index 72dc3ad0c..4780e68b5 100644 --- a/Source/NSFileManager.m +++ b/Source/NSFileManager.m @@ -30,7 +30,8 @@ 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., 51 Franklin Street, Fifth Floor, Boston, MA 02111 USA. + Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02111 USA. NSFileManager class reference $Date$ $Revision$ @@ -401,8 +402,8 @@ static NSStringEncoding defaultEncoding; { allOk = NO; str = [NSString stringWithFormat: - @"Unable to change NSFileOwnerAccountID to '%u' - %s", - num, GSLastErrorStr(errno)]; + @"Unable to change NSFileOwnerAccountID to '%u' - %@", + num, [NSError _last]]; ASSIGN(_lastError, str); } } @@ -425,8 +426,8 @@ static NSStringEncoding defaultEncoding; { allOk = NO; str = [NSString stringWithFormat: - @"Unable to change NSFileOwnerAccountName to '%@' - %s", - str, GSLastErrorStr(errno)]; + @"Unable to change NSFileOwnerAccountName to '%@' - %@", + str, [NSError _last]]; ASSIGN(_lastError, str); } } @@ -439,8 +440,8 @@ static NSStringEncoding defaultEncoding; { allOk = NO; str = [NSString stringWithFormat: - @"Unable to change NSFileGroupOwnerAccountID to '%u' - %s", - num, GSLastErrorStr(errno)]; + @"Unable to change NSFileGroupOwnerAccountID to '%u' - %@", + num, [NSError _last]]; ASSIGN(_lastError, str); } } @@ -461,8 +462,8 @@ static NSStringEncoding defaultEncoding; { allOk = NO; str = [NSString stringWithFormat: - @"Unable to change NSFileGroupOwnerAccountName to '%@' - %s", - str, GSLastErrorStr(errno)]; + @"Unable to change NSFileGroupOwnerAccountName to '%@' - %@", + str, [NSError _last]]; ASSIGN(_lastError, str); } } @@ -475,8 +476,8 @@ static NSStringEncoding defaultEncoding; { allOk = NO; str = [NSString stringWithFormat: - @"Unable to change NSFilePosixPermissions to '%o' - %s", - num, GSLastErrorStr(errno)]; + @"Unable to change NSFilePosixPermissions to '%o' - %@", + num, [NSError _last]]; ASSIGN(_lastError, str); } } @@ -519,8 +520,8 @@ static NSStringEncoding defaultEncoding; { allOk = NO; str = [NSString stringWithFormat: - @"Unable to change NSFileModificationDate to '%@' - %s", - date, GSLastErrorStr(errno)]; + @"Unable to change NSFileModificationDate to '%@' - %@", + date, [NSError _last]]; ASSIGN(_lastError, str); } } @@ -747,8 +748,8 @@ static NSStringEncoding defaultEncoding; { NSString *s; - s = [NSString stringWithFormat: @"Could not create '%s' - '%s'", - dirpath, GSLastErrorStr(errno)]; + s = [NSString stringWithFormat: @"Could not create '%s' - '%@'", + dirpath, [NSError _last]]; ASSIGN(_lastError, s); return NO; } @@ -1277,9 +1278,11 @@ static NSStringEncoding defaultEncoding; if (unlink(lpath) < 0) #endif { + NSString *message = [[NSError _last] localizedDescription]; + return [self _proceedAccordingToHandler: handler - forError: [NSString stringWithCString: GSLastErrorStr (errno)] - inPath: path]; + forError: message + inPath: path]; } else { @@ -1311,9 +1314,11 @@ static NSStringEncoding defaultEncoding; if (_RMDIR([self fileSystemRepresentationWithPath: path]) < 0) { + NSString *message = [[NSError _last] localizedDescription]; + return [self _proceedAccordingToHandler: handler - forError: [NSString stringWithCString: GSLastErrorStr (errno)] - inPath: path]; + forError: message + inPath: path]; } else { @@ -1947,7 +1952,7 @@ typedef struct _GSEnumeratedDirectory { } GSEnumeratedDirectory; -inline void gsedRelease(GSEnumeratedDirectory X) +static inline void gsedRelease(GSEnumeratedDirectory X) { DESTROY(X.path); _CLOSEDIR(X.pointer); @@ -2031,8 +2036,8 @@ inline void gsedRelease(GSEnumeratedDirectory X) } else { - NSLog(@"Failed to recurse into directory '%@' - %s", path, - GSLastErrorStr(errno)); + NSLog(@"Failed to recurse into directory '%@' - %@", path, + [NSError _last]); } return self; } @@ -2198,8 +2203,8 @@ inline void gsedRelease(GSEnumeratedDirectory X) } else { - NSLog(@"Failed to recurse into directory '%@' - %s", - _currentFilePath, GSLastErrorStr(errno)); + NSLog(@"Failed to recurse into directory '%@' - %@", + _currentFilePath, [NSError _last]); } } } @@ -2940,7 +2945,8 @@ static NSSet *fileKeys = nil; gp = getgrgid(statbuf.st_gid); if (gp != 0) { - group = [NSString stringWithCString: gp->gr_name]; + group = [NSString stringWithCString: gp->gr_name + encoding: defaultEncoding]; } #endif #endif @@ -3081,7 +3087,8 @@ static NSSet *fileKeys = nil; if (pw != 0) { - owner = [NSString stringWithCString: pw->pw_name]; + owner = [NSString stringWithCString: pw->pw_name + encoding: defaultEncoding]; } #endif /* HAVE_PWD_H */ #endif diff --git a/Source/NSFormatter.m b/Source/NSFormatter.m index 64f6575d7..e0ef202c8 100644 --- a/Source/NSFormatter.m +++ b/Source/NSFormatter.m @@ -18,7 +18,8 @@ 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., 51 Franklin Street, Fifth Floor, Boston, MA 02111 USA. + Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02111 USA. NSFormatter class reference $Date$ $Revision$ diff --git a/Source/NSGeometry.m b/Source/NSGeometry.m index fdbb9b190..820a2d828 100644 --- a/Source/NSGeometry.m +++ b/Source/NSGeometry.m @@ -18,7 +18,8 @@ * * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02111 USA. + * Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02111 USA. NSGeometry class reference $Date$ $Revision$ @@ -40,8 +41,7 @@ #include "Foundation/NSGeometry.h" #include "Foundation/NSScanner.h" #include "Foundation/NSNotification.h" - -extern BOOL GSMacOSXCompatibleGeometry(void); // Compatibility mode +#include "GSPrivate.h" static Class NSStringClass = 0; static Class NSScannerClass = 0; @@ -71,6 +71,13 @@ setupCache(void) } } +static BOOL GSMacOSXCompatibleGeometry(void) +{ + if (GSPrivateDefaultsFlag(GSOldStyleGeometry) == YES) + return NO; + return GSPrivateDefaultsFlag(GSMacOSXCompatible); +} + /**** Function Implementations ***********************************************/ /* Most of these are implemented in the header file as inline functkions */ diff --git a/Source/NSHTTPCookie.m b/Source/NSHTTPCookie.m index 95367c86c..2cf45e7e1 100644 --- a/Source/NSHTTPCookie.m +++ b/Source/NSHTTPCookie.m @@ -58,7 +58,7 @@ typedef struct { if (o != nil) { - o->_NSHTTPCookieInternal = NSZoneMalloc(z, sizeof(Internal)); + o->_NSHTTPCookieInternal = NSZoneCalloc(z, 1, sizeof(Internal)); } return o; } diff --git a/Source/NSHTTPCookieStorage.m b/Source/NSHTTPCookieStorage.m index 7a13e52f3..da11d088c 100644 --- a/Source/NSHTTPCookieStorage.m +++ b/Source/NSHTTPCookieStorage.m @@ -68,7 +68,7 @@ static NSHTTPCookieStorage *storage = nil; o = (NSHTTPCookieStorage*) NSAllocateObject(self, 0, NSDefaultMallocZone()); o->_NSHTTPCookieStorageInternal = (Internal*) - NSZoneMalloc(NSDefaultMallocZone(), sizeof(Internal)); + NSZoneCalloc(NSDefaultMallocZone(), 1, sizeof(Internal)); inst->_policy = NSHTTPCookieAcceptPolicyAlways; inst->_cookies = [NSMutableSet new]; storage = o; @@ -111,6 +111,8 @@ static NSHTTPCookieStorage *storage = nil; - (void) setCookie: (NSHTTPCookie *)cookie { + NSAssert([cookie isKindOfClass: [NSHTTPCookie class]] == YES, + NSInvalidArgumentException); [this->_cookies addObject: cookie]; } diff --git a/Source/NSHashTable.m b/Source/NSHashTable.m index 7be302240..6e88ea337 100644 --- a/Source/NSHashTable.m +++ b/Source/NSHashTable.m @@ -21,7 +21,8 @@ * * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02111 USA. + * Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02111 USA. * * NSHashTable class reference * $Date$ $Revision$ diff --git a/Source/NSHost.m b/Source/NSHost.m index 2528d1063..2d0ad8c44 100644 --- a/Source/NSHost.m +++ b/Source/NSHost.m @@ -20,7 +20,8 @@ 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., 51 Franklin Street, Fifth Floor, Boston, MA 02111 USA. + Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02111 USA. NSHost class reference $Date$ $Revision$ @@ -204,7 +205,7 @@ static NSMutableDictionary *_hostCache = nil; break; } - h_name = [NSString stringWithCString: entry->h_name]; + h_name = [NSString stringWithUTF8String: entry->h_name]; [names addObject: h_name]; if (entry->h_aliases != 0) @@ -212,7 +213,7 @@ static NSMutableDictionary *_hostCache = nil; i = 0; while ((ptr = entry->h_aliases[i++]) != 0) { - [names addObject: [NSString stringWithCString: ptr]]; + [names addObject: [NSString stringWithUTF8String: ptr]]; } } if (entry->h_addr_list != 0) @@ -223,7 +224,7 @@ static NSMutableDictionary *_hostCache = nil; NSString *addr; memcpy((void*)&in.s_addr, (const void*)ptr, entry->h_length); - addr = [NSString stringWithCString: (char*)inet_ntoa(in)]; + addr = [NSString stringWithUTF8String: (char*)inet_ntoa(in)]; [addresses addObject: addr]; } } diff --git a/Source/NSIndexPath.m b/Source/NSIndexPath.m index f739b011c..a6b5ba420 100644 --- a/Source/NSIndexPath.m +++ b/Source/NSIndexPath.m @@ -18,8 +18,8 @@ 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., 51 Franklin Street, - Fifth Floor, Boston, MA 02111 USA. + Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02111 USA. */ @@ -31,6 +31,7 @@ #include #include #include +#include "GNUstepBase/GSLock.h" static NSLock *lock = nil; static NSHashTable *shared = 0; @@ -72,7 +73,7 @@ static NSIndexPath *dummy = nil; dummy = (NSIndexPath*)NSAllocateObject(self, 0, NSDefaultMallocZone()); shared = NSCreateHashTable(NSNonRetainedObjectHashCallBacks, 1024); NSHashInsert(shared, empty); - lock = [NSLock new]; + lock = [GSLazyRecursiveLock new]; } } @@ -130,7 +131,7 @@ static NSIndexPath *dummy = nil; GSNOSUPERDEALLOC; } -- (NSString*)description +- (NSString*) description { NSMutableString *m = [[super description] mutableCopy]; unsigned i; @@ -425,5 +426,25 @@ static NSIndexPath *dummy = nil; return _length; } +- (void) release +{ + if (self != empty) + { + /* We lock the table while checking, to prevent + * another thread from grabbing this object while we are + * checking it. + * If we are going to deallocate the object, we first remove + * it from the table so that no other thread will find it + * and try to use it while it is being deallocated. + */ + [lock lock]; + if (NSDecrementExtraRefCountWasZero(self)) + { + [self dealloc]; + } + [lock unlock]; + } +} + @end diff --git a/Source/NSIndexSet.m b/Source/NSIndexSet.m index 8617b0fd1..c1d785fc0 100644 --- a/Source/NSIndexSet.m +++ b/Source/NSIndexSet.m @@ -247,14 +247,26 @@ static unsigned posForIndex(GSIArray array, unsigned index) unsigned c = (_array == 0) ? 0 : GSIArrayCount(_array); unsigned i; + if (c == 0) + { + return [NSString stringWithFormat: @"%@(no indexes)", + [super description]]; + } m = [NSMutableString stringWithFormat: - @"%@[number of indexes: %u (in %u ranges), indexes: ", + @"%@[number of indexes: %u (in %u ranges), indexes:", [super description], [self count], c]; for (i = 0; i < c; i++) { NSRange r = GSIArrayItemAtIndex(_array, i).ext; - [m appendFormat: @"(%u-%u) ", r.location, NSMaxRange(r) - 1]; + if (r.length > 1) + { + [m appendFormat: @" (%u-%u)", r.location, NSMaxRange(r) - 1]; + } + else + { + [m appendFormat: @" (%u)", r.location]; + } } [m appendString: @"]"]; return m; @@ -968,3 +980,77 @@ static unsigned posForIndex(GSIArray array, unsigned index) @end +@implementation NSIndexSet (NSCharacterSet) +/* Extra method to let NSCharacterSet play with index sets more efficiently. + */ +- (unsigned int) _gapGreaterThanIndex: (unsigned int)anIndex +{ + unsigned pos; + NSRange r; + + if (anIndex++ == NSNotFound) + { + return NSNotFound; + } + if (_array == 0 || GSIArrayCount(_array) == 0) + { + return NSNotFound; + } + + if ((pos = posForIndex(_array, anIndex)) >= GSIArrayCount(_array)) + { + r = GSIArrayItemAtIndex(_array, pos-1).ext; + if (anIndex > NSMaxRange(r)) + { + return NSNotFound; + } + return anIndex; // anIndex is the gap after the last index. + } + r = GSIArrayItemAtIndex(_array, pos).ext; + if (r.location > anIndex) + { + return anIndex; // anIndex is in a gap between index ranges. + } + return NSMaxRange(r); // Return start of gap after the index range. +} + +@end + +/* A subclass used to access a pre-generated table of information on the + * stack or in other non-heap allocated memory. + */ +@interface _GSStaticIndexSet : NSIndexSet +@end + +@implementation _GSStaticIndexSet +- (void) dealloc +{ + if (_array != 0) + { + /* Free the array without freeing its static content. + */ + NSZoneFree([self zone], _array); + _data = 0; + } + [super dealloc]; +} + +- (id) _initWithBytes: (const void*)bytes length: (unsigned)length +{ + NSAssert(length % sizeof(NSRange) == 0, NSInvalidArgumentException); + length /= sizeof(NSRange); + _data = NSZoneMalloc([self zone], sizeof(GSIArray_t)); + _array->ptr = (GSIArrayItem*)bytes; + _array->count = length; + _array->cap = length; + _array->old = length; + _array->zone = 0; + return self; +} + +- (id) init +{ + return [self _initWithBytes: 0 length: 0]; +} +@end + diff --git a/Source/NSInvocation.m b/Source/NSInvocation.m index 5b9b05d40..32b2b5d38 100644 --- a/Source/NSInvocation.m +++ b/Source/NSInvocation.m @@ -648,13 +648,13 @@ _arg_addr(NSInvocation *inv, int index) char buffer[1024]; snprintf (buffer, 1024, "<%s %p selector: %s target: %s>", \ - GSClassNameFromObject(self), \ - self, \ - _selector ? GSNameFromSelector(_selector) : "nil", \ - _target ? GSNameFromClass([_target class]) : "nil" \ - ); + GSClassNameFromObject(self), \ + self, \ + _selector ? GSNameFromSelector(_selector) : "nil", \ + _target ? GSNameFromClass([_target class]) : "nil" \ + ); - return [NSString stringWithCString: buffer]; + return [NSString stringWithUTF8String: buffer]; } - (void) encodeWithCoder: (NSCoder*)aCoder diff --git a/Source/NSKeyedArchiver.m b/Source/NSKeyedArchiver.m index 128d6e287..91b4171fd 100644 --- a/Source/NSKeyedArchiver.m +++ b/Source/NSKeyedArchiver.m @@ -669,7 +669,7 @@ static NSDictionary *makeReference(unsigned ref) * Bizzarely MacOS-X seems to encode char* values by creating * string objects and encoding those objects! */ - o = [NSString stringWithCString: (char*)address]; + o = [NSString stringWithUTF8String: (char*)address]; [self encodeObject: o]; } return; diff --git a/Source/NSLock.m b/Source/NSLock.m index 11f2f4ca4..42be79457 100644 --- a/Source/NSLock.m +++ b/Source/NSLock.m @@ -19,7 +19,8 @@ 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., 51 Franklin Street, Fifth Floor, Boston, MA 02111 USA. + Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02111 USA. NSLock class reference $Date$ $Revision$ diff --git a/Source/NSLog.m b/Source/NSLog.m index 8812cc47f..03383c22b 100644 --- a/Source/NSLog.m +++ b/Source/NSLog.m @@ -18,7 +18,8 @@ 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., 51 Franklin Street, Fifth Floor, Boston, MA 02111 USA. + Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02111 USA. NSLog reference $Date$ $Revision$ @@ -144,7 +145,7 @@ _NSLog_standard_printf_handler (NSString* message) OutputDebugStringW(null_terminated_buf); - if ((GSUserDefaultsFlag(GSLogSyslog) == YES + if ((GSPrivateDefaultsFlag(GSLogSyslog) == YES || write(_NSLogDescriptor, buf, len) != (int)len) && !IsDebuggerPresent()) { static HANDLE eventloghandle = 0; @@ -170,7 +171,7 @@ _NSLog_standard_printf_handler (NSString* message) #else #if defined(HAVE_SYSLOG) - if (GSUserDefaultsFlag(GSLogSyslog) == YES + if (GSPrivateDefaultsFlag(GSLogSyslog) == YES || write(_NSLogDescriptor, buf, len) != (int)len) { null_terminated_buf = objc_malloc (sizeof (char) * (len + 1)); @@ -302,9 +303,9 @@ NSLogv (NSString* format, va_list args) } #ifdef HAVE_SYSLOG - if (GSUserDefaultsFlag(GSLogSyslog) == YES) + if (GSPrivateDefaultsFlag(GSLogSyslog) == YES) { - if (GSUserDefaultsFlag(GSLogThread) == YES) + if (GSPrivateDefaultsFlag(GSLogThread) == YES) { prefix = [NSString stringWithFormat: @"[thread:%x] ", GSCurrentThread()]; @@ -317,7 +318,7 @@ NSLogv (NSString* format, va_list args) else #endif { - if (GSUserDefaultsFlag(GSLogThread) == YES) + if (GSPrivateDefaultsFlag(GSLogThread) == YES) { prefix = [NSString stringWithFormat: @"%@ %@[%d,%x] ", diff --git a/Source/NSMessagePort.m b/Source/NSMessagePort.m index 73205cc44..89c5f7eee 100644 --- a/Source/NSMessagePort.m +++ b/Source/NSMessagePort.m @@ -18,8 +18,8 @@ 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., - 51 Franklin Street, Fifth Floor, Boston, MA 02111 USA. + Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02111 USA. */ #include "config.h" @@ -44,6 +44,7 @@ #include "Foundation/NSFileManager.h" #include "Foundation/NSProcessInfo.h" +#include "GSPrivate.h" #include "GSPortPrivate.h" #include @@ -302,15 +303,15 @@ static Class runLoopClass; e |= NBLK_OPT; if (fcntl(d, F_SETFL, e) < 0) { - NSLog(@"unable to set non-blocking mode on %d - %s", - d, GSLastErrorStr(errno)); + NSLog(@"unable to set non-blocking mode on %d - %@", + d, [NSError _last]); return nil; } } else { - NSLog(@"unable to get non-blocking mode on %d - %s", - d, GSLastErrorStr(errno)); + NSLog(@"unable to get non-blocking mode on %d - %@", + d, [NSError _last]); return nil; } handle = (GSMessageHandle*)NSAllocateObject(self, 0, NSDefaultMallocZone()); @@ -379,9 +380,8 @@ static Class runLoopClass; { if (errno != EINPROGRESS) { - NSLog(@"unable to make connection to %s - %s", - sockAddr.sun_path, - GSLastErrorStr(errno)); + NSLog(@"unable to make connection to %s - %@", + sockAddr.sun_path, [NSError _last]); M_UNLOCK(myLock); return NO; } @@ -607,7 +607,7 @@ static Class runLoopClass; else if (errno != EINTR && errno != EAGAIN) { NSDebugMLLog(@"NSMessagePort", - @"read failed - %s on 0x%x", GSLastErrorStr(errno), self); + @"read failed - %@ on 0x%p", [NSError _last], self); M_UNLOCK(myLock); [self invalidate]; return; @@ -902,11 +902,16 @@ static Class runLoopClass; int res = 0; unsigned len = sizeof(res); - if (getsockopt(desc, SOL_SOCKET, SO_ERROR, (char*)&res, &len) == 0 - && res != 0) + if (getsockopt(desc, SOL_SOCKET, SO_ERROR, (char*)&res, &len) != 0) { state = GS_H_UNCON; - NSLog(@"connect attempt failed - %s", GSLastErrorStr(res)); + NSLog(@"connect attempt failed - %@", [NSError _last]); + } + else if (res != 0) + { + state = GS_H_UNCON; + NSLog(@"connect attempt failed - %@", + [NSError _systemError: res]); } else { @@ -922,8 +927,8 @@ static Class runLoopClass; else { state = GS_H_UNCON; - NSLog(@"connect write attempt failed - %s", - GSLastErrorStr(errno)); + NSLog(@"connect write attempt failed - %@", + [NSError _last]); } RELEASE(d); } @@ -957,7 +962,7 @@ static Class runLoopClass; { if (errno != EINTR && errno != EAGAIN) { - NSLog(@"write attempt failed - %s", GSLastErrorStr(errno)); + NSLog(@"write attempt failed - %@", [NSError _last]); M_UNLOCK(myLock); [self invalidate]; return; @@ -1249,7 +1254,7 @@ typedef struct { sizeof(sockAddr.sun_path)); if ((desc = socket(PF_LOCAL, SOCK_STREAM, PF_UNSPEC)) < 0) { - NSLog(@"unable to create socket - %s", GSLastErrorStr(errno)); + NSLog(@"unable to create socket - %@", [NSError _last]); desc = -1; } else if (bind(desc, (struct sockaddr *)&sockAddr, @@ -1263,23 +1268,23 @@ typedef struct { close(desc); if ((desc = socket(PF_LOCAL, SOCK_STREAM, PF_UNSPEC)) < 0) { - NSLog(@"unable to create socket - %s", - GSLastErrorStr(errno)); + NSLog(@"unable to create socket - %@", + [NSError _last]); desc = -1; } else if (bind(desc, (struct sockaddr *)&sockAddr, SUN_LEN(&sockAddr)) < 0) { - NSLog(@"unable to bind to %s - %s", - sockAddr.sun_path, GSLastErrorStr(errno)); + NSLog(@"unable to bind to %s - %@", + sockAddr.sun_path, [NSError _last]); (void) close(desc); desc = -1; } } else { - NSLog(@"unable to bind to %s - %s", - sockAddr.sun_path, GSLastErrorStr(errno)); + NSLog(@"unable to bind to %s - %@", + sockAddr.sun_path, [NSError _last]); (void) close(desc); desc = -1; } @@ -1291,13 +1296,13 @@ typedef struct { } else if (listen(desc, 128) < 0) { - NSLog(@"unable to listen on port - %s", GSLastErrorStr(errno)); + NSLog(@"unable to listen on port - %@", [NSError _last]); (void) close(desc); DESTROY(port); } else if (getsockname(desc, (struct sockaddr*)&sockAddr, &i) < 0) { - NSLog(@"unable to get socket name - %s", GSLastErrorStr(errno)); + NSLog(@"unable to get socket name - %@", [NSError _last]); (void) close(desc); DESTROY(port); } @@ -1492,7 +1497,7 @@ typedef struct { sock = socket(PF_LOCAL, SOCK_STREAM, PF_UNSPEC); if (sock < 0) { - NSLog(@"unable to create socket - %s", GSLastErrorStr(errno)); + NSLog(@"unable to create socket - %@", [NSError _last]); } #ifndef BROKEN_SO_REUSEADDR /* @@ -1505,13 +1510,13 @@ typedef struct { sizeof(opt)) < 0) { (void)close(sock); - NSLog(@"unable to set reuse on socket - %s", GSLastErrorStr(errno)); + NSLog(@"unable to set reuse on socket - %@", [NSError _last]); } #endif else if ((handle = [GSMessageHandle handleWithDescriptor: sock]) == nil) { (void)close(sock); - NSLog(@"unable to create GSMessageHandle - %s", GSLastErrorStr(errno)); + NSLog(@"unable to create GSMessageHandle - %@", [NSError _last]); } else { @@ -1574,14 +1579,14 @@ typedef struct { unsigned i; M_LOCK(messagePortLock); + NSMapRemove(messagePortMap, (void*)name); + M_UNLOCK(messagePortLock); if (lDesc >= 0) { (void) close(lDesc); unlink([name bytes]); lDesc = -1; } - NSMapRemove(messagePortMap, (void*)name); - M_UNLOCK(messagePortLock); if (handles != 0) { @@ -1691,6 +1696,24 @@ typedef struct { } } +- (void) release +{ + M_LOCK(messagePortLock); + if (NSDecrementExtraRefCountWasZero(self)) + { + if (_internal != 0) + { + NSMapRemove(messagePortMap, (void*)name); + } + M_UNLOCK(messagePortLock); + [self dealloc]; + } + else + { + M_UNLOCK(messagePortLock); + } +} + - (void) removeHandle: (GSMessageHandle*)handle { M_LOCK(myLock); diff --git a/Source/NSMessagePortNameServer.m b/Source/NSMessagePortNameServer.m index 10a158680..8890953ee 100644 --- a/Source/NSMessagePortNameServer.m +++ b/Source/NSMessagePortNameServer.m @@ -16,8 +16,8 @@ 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., 51 Franklin Street, Fifth Floor, Boston, - MA 02111 USA. + Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02111 USA. NSMessagePortNameServer class reference $Date$ $Revision$ @@ -252,6 +252,10 @@ static void clean_up_names(void) } } +- (NSPort*) portForName: (NSString*)name +{ + return [self portForName: name onHost: nil]; +} - (NSPort*) portForName: (NSString *)name onHost: (NSString *)host @@ -262,10 +266,15 @@ static void clean_up_names(void) NSDebugLLog(@"NSMessagePort", @"portForName: %@ host: %@", name, host); - if ([host length] && ![host isEqual: @"*"]) + if ([host length] > 0) { - NSDebugLLog(@"NSMessagePort", @"non-local host"); - return nil; + [NSException raise: NSInvalidArgumentException + format: @"Attempt to contact a named host using a " + @"message port name server. This name server can only be used " + @"to contact processes owned by the same user on the local host " + @"(host name must be an empty string). To contact processes " + @"owned by other users or on other hosts you must use an instance " + @"of the NSSocketPortNameServer class."]; } path = [[self class] _pathForName: name]; diff --git a/Source/NSMethodSignature.m b/Source/NSMethodSignature.m index 8a2a33641..81719e4ee 100644 --- a/Source/NSMethodSignature.m +++ b/Source/NSMethodSignature.m @@ -20,7 +20,8 @@ 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., 51 Franklin Street, Fifth Floor, Boston, MA 02111 USA. + Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02111 USA. NSMethodSignature class reference $Date$ $Revision$ diff --git a/Source/NSNetServices.m b/Source/NSNetServices.m new file mode 100644 index 000000000..078f028ab --- /dev/null +++ b/Source/NSNetServices.m @@ -0,0 +1,3321 @@ +/* Implementation for NSNetServices for GNUstep + Copyright (C) 2006 Free Software Foundation, Inc. + + Written by: Chris B. Vetter + Date: 2006 + + 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., 51 Franklin Street, Fifth Floor, + Boston, MA 02111 USA. + */ + +#import "Foundation/NSNetServices.h" +#import "Foundation/NSData.h" +#import "Foundation/NSDebug.h" +#import "Foundation/NSNull.h" +#import "Foundation/NSRunLoop.h" +#import "Foundation/NSStream.h" +#import "Foundation/NSTimer.h" +#import "Foundation/NSValue.h" +#if defined(_REENTRANT) +#import "GNUstepBase/GSLock.h" +#endif + +#import // Apple's DNS Service Discovery + +#import +#import // AF_INET / AF_INET6 + +#import // struct sockaddr_in / sockaddr_in6 +#import // inet_pton(3) + +// +// Define +// + +#if ! defined(INET6_ADDRSTRLEN) +# define INET6_ADDRSTRLEN 46 +#endif + +// trigger runloop timer every INTERVAL seconds +#define INTERVAL 0.3 +#define SHORTTIMEOUT 0.25 + +// debugging stuff and laziness on my part +#if defined(VERBOSE) +# define INTERNALTRACE NSDebugLLog(@"Trace", @"%s", __PRETTY_FUNCTION__) +# define LOG(f, args...) NSDebugLLog(@"NSNetServices", f, ##args) +#else +# define INTERNALTRACE +# define LOG(f, args...) +#endif /* VERBOSE */ + +#if ! defined(VERSION) +# define VERSION (((GNUSTEP_BASE_MAJOR_VERSION * 100) \ + + GNUSTEP_BASE_MINOR_VERSION) * 100) \ + + GNUSTEP_BASE_SUBMINOR_VERSION +#endif + +#define SETVERSION(aClass) \ + do { \ + if (self == [aClass class]) { [self setVersion: VERSION]; } \ + else { [self doesNotRecognizeSelector: _cmd]; } \ + } while(0); + +#if defined(_REENTRANT) +# define THE_LOCK GSLazyRecursiveLock *lock +# define CREATELOCK(x) x->lock = [GSLazyRecursiveLock new] +# define LOCK(x) [x->lock lock] +# define UNLOCK(x) [x->lock unlock] +# define DESTROYLOCK(x) DESTROY(x->lock) +#else +# define THE_LOCK /* nothing */ +# define CREATELOCK(x) /* nothing */ +# define LOCK(x) /* nothing */ +# define UNLOCK(x) /* nothing */ +# define DESTROYLOCK(x) /* nothing */ +#endif + +// +// Typedef +// + +typedef struct _Browser // The actual NSNetServiceBrowser +{ + THE_LOCK; + + NSRunLoop *runloop; + NSString *runloopmode; + NSTimer *timer; // to control the runloop + + NSMutableDictionary *services; + // List of found services. + // Key is <_name_type_domain> and value is an initialized NSNetService. + + int interfaceIndex; +} Browser; + +typedef struct _Service // The actual NSNetService +{ + THE_LOCK; + + NSRunLoop *runloop; + NSString *runloopmode; + NSTimer *timer, // to control the runloop + *timeout; // to time-out the resolve + + NSMutableDictionary *info; + // The service's information, keys are + // - Domain (string) + // - Name (string) + // - Type (string) + // - Host (string) + // - Addresses (mutable array) + // - TXT (data) + + NSMutableArray *foundAddresses; // array of char* + + int interfaceIndex, // should also be in 'info' + port; // ditto + + id monitor; // NSNetServiceMonitor + + BOOL isPublishing, // true if publishing service + isMonitoring; // true if monitoring +} Service; + +typedef struct _Monitor // The actual NSNetServiceMonitor +{ + THE_LOCK; + + NSRunLoop *runloop; + NSString *runloopmode; + NSTimer *timer; // to control the runloop +} Monitor; + +// +// Public +// + +/** + * This key identifies the most recent error. + */ +NSString * const NSNetServicesErrorCode = @"NSNetServicesErrorCode"; + +/** + * This key identifies the originator of the error. + */ +NSString * const NSNetServicesErrorDomain = @"NSNetServicesErrorDomain"; + +// +// Private +// + +// +// Private Interface +// + +@interface NSNetServiceMonitor : NSObject +{ + @private + void * _netServiceMonitor; + id _delegate; + void * _reserved; +} + +- (id) initWithDelegate: (id) delegate; + +- (void) removeFromRunLoop: (NSRunLoop *) aRunLoop + forMode: (NSString *) mode; +- (void) scheduleInRunLoop: (NSRunLoop *) aRunLoop + forMode: (NSString *) mode; + +- (void) start; +- (void) stop; + +@end + +// +// Prototype +// + +static NSDictionary *CreateError(id sender, int errorCode); + +static int ConvertError(int errorCode); + +static void DNSSD_API + // used by NSNetServiceBrowser + EnumerationCallback(DNSServiceRef sdRef, + DNSServiceFlags flags, + uint32_t interfaceIndex, + DNSServiceErrorType errorCode, + const char *replyDomain, + void *context); + +static void DNSSD_API + BrowserCallback(DNSServiceRef sdRef, + DNSServiceFlags flags, + uint32_t interfaceIndex, + DNSServiceErrorType errorCode, + const char *replyName, + const char *replyType, + const char *replyDomain, + void *context); + +static void DNSSD_API + // used by NSNetService + ResolverCallback(DNSServiceRef sdRef, + DNSServiceFlags flags, + uint32_t interfaceIndex, + DNSServiceErrorType errorCode, + const char *fullname, + const char *hosttarget, + uint16_t port, + uint16_t txtLen, + const char *txtRecord, + void *context); + +static void DNSSD_API + RegistrationCallback(DNSServiceRef sdRef, + DNSServiceFlags flags, + DNSServiceErrorType errorCode, + const char *name, + const char *regtype, + const char *domain, + void *context); + +static void DNSSD_API + // used by NSNetService and NSNetServiceMonitor + QueryCallback(DNSServiceRef sdRef, + DNSServiceFlags flags, + uint32_t interfaceIndex, + DNSServiceErrorType errorCode, + const char *fullname, + uint16_t rrtype, + uint16_t rrclass, + uint16_t rdlen, + const void *rdata, + uint32_t ttl, + void *context); + +/*************************************************************************** +** +** Implementation +** +*/ + +@implementation NSNetServiceBrowser + +/** + * Description forthcoming + * + * + */ + ++ (void) initialize +{ + INTERNALTRACE; + + SETVERSION(NSNetServiceBrowser); + { +#ifndef _REENTRANT + LOG(@"%@ may NOT be thread-safe!", [self class]); +#endif + } +} + +/*************************************************************************** +** +** Private Methods +** +*/ + +/** + * Description forthcoming + * + * + */ + +- (void) cleanup +{ + Browser *browser; + + INTERNALTRACE; + + browser = (Browser *) _reserved; + + LOCK(browser); + { + if (browser->runloop) + { + [self removeFromRunLoop: browser->runloop + forMode: browser->runloopmode]; + } + + if (browser->timer) + { + [browser->timer invalidate]; + DESTROY(browser->timer); + } + + if (_netServiceBrowser) + { + DNSServiceRefDeallocate(_netServiceBrowser); + _netServiceBrowser = NULL; + } + + [browser->services removeAllObjects]; + } + UNLOCK(browser); +} + +/** + * Description forthcoming + * + * + */ + +- (void) executeWithError: (DNSServiceErrorType) err +{ + Browser *browser; + + INTERNALTRACE; + + browser = (Browser *) _reserved; + + LOCK(browser); + { + if (kDNSServiceErr_NoError == err) + { + [self netServiceBrowserWillSearch: self]; + + if (! browser->runloop) + { + [self scheduleInRunLoop: [NSRunLoop currentRunLoop] + forMode: NSDefaultRunLoopMode]; + } + + [browser->runloop addTimer: browser->timer + forMode: browser->runloopmode]; + + [browser->timer fire]; + } + else // notify the delegate of the error + { + [self netServiceBrowser: self + didNotSearch: CreateError(self, err)]; + } + } + UNLOCK(browser); +} + +/** + * Description forthcoming + * + * + */ + +- (void) searchForDomain: (int) aFlag +{ + DNSServiceErrorType err = kDNSServiceErr_NoError; + Browser *browser; + + INTERNALTRACE; + + browser = (Browser *) _reserved; + + LOCK(browser); + { + do + { + if (! _delegate) + { + err = NSNetServicesInvalidError; + break; + } + + if (browser->timer) + { + err = NSNetServicesActivityInProgress; + break; + } + + err = DNSServiceEnumerateDomains((DNSServiceRef *)&_netServiceBrowser, + aFlag, + browser->interfaceIndex, + EnumerationCallback, + self); + } + while(0); + } + UNLOCK(browser); + + [self executeWithError: err]; +} + +/** + * Description forthcoming + * + * + */ + +- (void) enumCallback: (DNSServiceRef) sdRef + flags: (DNSServiceFlags) flags + interface: (uint32_t) interfaceIndex + error: (DNSServiceErrorType) errorCode + domain: (const char *) replyDomain +{ + Browser *browser; + + INTERNALTRACE; + + browser = (Browser *) _reserved; + + LOCK(browser); + + if (_netServiceBrowser) + { + if (errorCode) + { + [self cleanup]; + + [self netServiceBrowser: self + didNotSearch: CreateError(self, errorCode)]; + } + else + { + BOOL more = NO; + + if (replyDomain) + { + NSString *domain; + + more = flags & kDNSServiceFlagsMoreComing; + + browser->interfaceIndex = interfaceIndex; + + domain = [NSString stringWithUTF8String: replyDomain]; + + if (flags & kDNSServiceFlagsAdd) + { + LOG(@"Found domain <%s>", replyDomain); + + [self netServiceBrowser: self + didFindDomain: domain + moreComing: more]; + } + else // kDNSServiceFlagsRemove + { + LOG(@"Removed domain <%s>", replyDomain); + + [self netServiceBrowser: self + didRemoveDomain: domain + moreComing: more]; + } + } + } + } + UNLOCK(browser); +} + +/** + * Description forthcoming + * + * + */ + +- (void) browseCallback: (DNSServiceRef) sdRef + flags: (DNSServiceFlags) flags + interface: (uint32_t) interfaceIndex + error: (DNSServiceErrorType) errorCode + name: (const char *) replyName + type: (const char *) replyType + domain: (const char *) replyDomain +{ + Browser *browser; + + INTERNALTRACE; + + browser = (Browser *) _reserved; + + LOCK(browser); + + if (_netServiceBrowser) + { + if (errorCode) + { + [self cleanup]; + + [self netServiceBrowser: self + didNotSearch: CreateError(self, errorCode)]; + } + else + { + NSNetService *service = nil; + NSString *domain = nil; + NSString *type = nil; + NSString *name = nil; + NSString *key = nil; + BOOL more = (flags & kDNSServiceFlagsMoreComing); + + browser->interfaceIndex = interfaceIndex; + + if (nil == browser->services) + { + browser->services + = [[NSMutableDictionary alloc] initWithCapacity: 1]; + } + + domain = [NSString stringWithUTF8String: replyDomain]; + type = [NSString stringWithUTF8String: replyType]; + name = [NSString stringWithUTF8String: replyName]; + + key = [NSString stringWithFormat: @"%@%@%@", name, type, domain]; + + if (flags & kDNSServiceFlagsAdd) + { + service = [[NSNetService alloc] initWithDomain: domain + type: type + name: name]; + + if (service) + { + LOG(@"Found service <%s>", replyName); + + [self netServiceBrowser: self + didFindService: service + moreComing: more]; + + [browser->services setObject: service + forKey: key]; + + [service autorelease]; + } + else + { + LOG(@"WARNING: Could not create an NSNetService for <%s>", + replyName); + } + } + else // kDNSServiceFlagsRemove + { + service = [browser->services objectForKey: key]; + + if (service) + { + LOG(@"Removed service <%@>", [service name]); + + [self netServiceBrowser: self + didRemoveService: service + moreComing: more]; + } + else + { + LOG(@"WARNING: Could not find <%@> in list", key); + } + } + } + } + UNLOCK(browser); +} + +/** + * Description forthcoming + * + * + */ + +- (void) loop: (id) sender +{ + int sock = 0; + struct timeval tout = { 0 }; + fd_set set; + DNSServiceErrorType err = kDNSServiceErr_NoError; + + sock = DNSServiceRefSockFD(_netServiceBrowser); + + if (-1 != sock) + { + FD_ZERO(&set); + FD_SET(sock, &set); + + if (1 == select(sock + 1, &set, (fd_set *) NULL, (fd_set *) NULL, &tout)) + { + err = DNSServiceProcessResult(_netServiceBrowser); + } + } + + if (kDNSServiceErr_NoError != err) + { + [self netServiceBrowser: self + didNotSearch: CreateError(self, err)]; + } +} + +/** + * Removes the receiver from the specified runloop. + * + * + */ +- (void) removeFromRunLoop: (NSRunLoop *) aRunLoop + forMode: (NSString *) mode +{ + Browser *browser; + + INTERNALTRACE; + + browser = (Browser *) _reserved; + + LOCK(browser); + { + if (browser->timer) + { + [browser->timer setFireDate: [NSDate date]]; + [browser->timer invalidate]; + browser->timer = nil; + } + + // Do not release the runloop! + browser->runloop = nil; + + DESTROY(browser->runloopmode); + } + UNLOCK(browser); +} + +/** + * Adds the receiver to the specified runloop. + * + * + */ + +- (void) scheduleInRunLoop: (NSRunLoop *) aRunLoop + forMode: (NSString *) mode +{ + Browser *browser; + + INTERNALTRACE; + + browser = (Browser *) _reserved; + + LOCK(browser); + { + if (browser->timer) + { + [browser->timer setFireDate: [NSDate date]]; + [browser->timer invalidate]; + browser->timer = nil; + } + + browser->timer = [NSTimer timerWithTimeInterval: INTERVAL + target: self + selector: @selector(loop:) + userInfo: nil + repeats: YES]; + + browser->runloop = aRunLoop; + browser->runloopmode = mode; + + [browser->timer retain]; + } + UNLOCK(browser); +} + +/** + * Search for all visible domains. This method is deprecated. + * + * + */ + +- (void) searchForAllDomains +{ + DNSServiceFlags flags = 0; + + INTERNALTRACE; + + flags = kDNSServiceFlagsBrowseDomains|kDNSServiceFlagsRegistrationDomains; + [self searchForDomain: flags]; +} + +/** + * Search for all browsable domains. + * + * + */ + +- (void) searchForBrowsableDomains +{ + INTERNALTRACE; + + [self searchForDomain: kDNSServiceFlagsBrowseDomains]; +} + +/** + * Search for all registration domains. These domains can be used to register + * a service. + * + */ + +- (void) searchForRegistrationDomains +{ + INTERNALTRACE; + + [self searchForDomain: kDNSServiceFlagsRegistrationDomains]; +} + +/** + * Search for a particular service within a given domain. + * + * + */ + +- (void) searchForServicesOfType: (NSString *) serviceType + inDomain: (NSString *) domainName +{ + Browser *browser; + DNSServiceErrorType err = kDNSServiceErr_NoError; + DNSServiceFlags flags = 0; + + INTERNALTRACE; + + browser = (Browser *) _reserved; + + LOCK(browser); + { + do + { + if (! _delegate) + { + err = NSNetServicesInvalidError; + break; + } + + if (browser->timer) + { + err = NSNetServicesActivityInProgress; + break; + } + + err = DNSServiceBrowse((DNSServiceRef *) &_netServiceBrowser, + flags, + browser->interfaceIndex, + [serviceType UTF8String], + [domainName UTF8String], + BrowserCallback, + self); + } + while(0); + } + UNLOCK(browser); + + [self executeWithError: err]; +} + +/** + * Halts all currently running searches. + * + * + */ + +- (void) stop +{ + Browser *browser; + + INTERNALTRACE; + + browser = (Browser *) _reserved; + + LOCK(browser); + { + [self cleanup]; + + [self netServiceBrowserDidStopSearch: self]; + } + UNLOCK(browser); +} + +/** + * Returns the receiver's delegate. + * + * + */ + +- (id) delegate +{ + INTERNALTRACE; + + return [[_delegate retain] autorelease]; +} + +/** + * Sets the receiver's delegate. + * + * + */ + +- (void) setDelegate: (id) delegate +{ + INTERNALTRACE; + + ASSIGN(_delegate, delegate); +} + +/** + * Description forthcoming + * + * + */ + +- (void) netServiceBrowserWillSearch: (NSNetServiceBrowser *) aBrowser +{ + INTERNALTRACE; + + if ([_delegate respondsToSelector: @selector(netServiceBrowserWillSearch:)]) + { + [_delegate netServiceBrowserWillSearch: aBrowser]; + } +} + +/** + * Description forthcoming + * + * + */ + +- (void) netServiceBrowser: (NSNetServiceBrowser *) aBrowser + didNotSearch: (NSDictionary *) errorDict +{ + INTERNALTRACE; + + if ([_delegate respondsToSelector: + @selector(netServiceBrowser:didNotSearch:)]) + { + [_delegate netServiceBrowser: aBrowser + didNotSearch: errorDict]; + } +} + +/** + * Description forthcoming + * + * + */ + +- (void) netServiceBrowserDidStopSearch: (NSNetServiceBrowser *) aBrowser +{ + INTERNALTRACE; + + if ([_delegate respondsToSelector: + @selector(netServiceBrowserDidStopSearch:)]) + { + [_delegate netServiceBrowserDidStopSearch: aBrowser]; + } +} + +/** + * Description forthcoming + * + * + */ + +- (void) netServiceBrowser: (NSNetServiceBrowser *) aBrowser + didFindDomain: (NSString *) domainString + moreComing: (BOOL) moreComing +{ + INTERNALTRACE; + + if ([_delegate respondsToSelector: + @selector(netServiceBrowser:didFindDomain:moreComing:)]) + { + [_delegate netServiceBrowser: aBrowser + didFindDomain: domainString + moreComing: moreComing]; + } +} + +/** + * Description forthcoming + * + * + */ + +- (void) netServiceBrowser: (NSNetServiceBrowser *) aBrowser + didRemoveDomain: (NSString *) domainString + moreComing: (BOOL) moreComing +{ + INTERNALTRACE; + + if ([_delegate respondsToSelector: + @selector(netServiceBrowser:didRemoveDomain:moreComing:)]) + { + [_delegate netServiceBrowser: aBrowser + didRemoveDomain: domainString + moreComing: moreComing]; + } +} + +/** + * Description forthcoming + * + * + */ + +- (void) netServiceBrowser: (NSNetServiceBrowser *) aBrowser + didFindService: (NSNetService *) aService + moreComing: (BOOL) moreComing +{ + INTERNALTRACE; + + if ([_delegate respondsToSelector: + @selector(netServiceBrowser:didFindService:moreComing:)]) + { + [_delegate netServiceBrowser: aBrowser + didFindService: aService + moreComing: moreComing]; + } +} + +/** + * Description forthcoming + * + * + */ + +- (void) netServiceBrowser: (NSNetServiceBrowser *) aBrowser + didRemoveService: (NSNetService *) aService + moreComing: (BOOL) moreComing +{ + INTERNALTRACE; + + if ([_delegate respondsToSelector: + @selector(netServiceBrowser:didRemoveService:moreComing:)]) + { + [_delegate netServiceBrowser: aBrowser + didRemoveService: aService + moreComing: moreComing]; + } +} + +/** + * Initializes the receiver. + * + * + */ + +- (id) init +{ + INTERNALTRACE; + + if ((self = [super init])) + { + Browser *browser; + + browser = malloc(sizeof (struct _Browser)); + memset(browser, 0, sizeof browser); + + CREATELOCK(browser); + + browser->runloop = nil; + browser->runloopmode = nil; + browser->timer = nil; + + browser->services = [[NSMutableDictionary alloc] initWithCapacity: 1]; + + browser->interfaceIndex = 0; + + _netServiceBrowser = NULL; + _delegate = nil; + _reserved = browser; + } + return self; +} + +/** + * Description forthcoming + * + * + */ + +- (void) dealloc +{ + Browser *browser; + + INTERNALTRACE; + + browser = (Browser *) _reserved; + { + LOCK(browser); + { + [self cleanup]; + + DESTROY(browser->services); + + _delegate = nil; + } + UNLOCK(browser); + + DESTROYLOCK(browser); + + free(browser); + } + [super dealloc]; +} + +@end + +@implementation NSNetService + +/** + * Description forthcoming + * + * + */ + ++ (void) initialize +{ + INTERNALTRACE; + + SETVERSION(NSNetService); + { +#ifndef _REENTRANT + LOG(@"%@ may NOT be thread-safe!", [self class]); +#endif + } +} + +/** + * Description forthcoming + * + * + */ + +- (void) executeWithError: (DNSServiceErrorType) err +{ + Service *service; + + INTERNALTRACE; + + service = (Service *) _reserved; + + LOCK(service); + { + if (kDNSServiceErr_NoError == err) + { + if (YES == service->isPublishing) + { + [self netServiceWillPublish: self]; + } + else + { + [self netServiceWillResolve: self]; + } + + if (! service->runloop) + { + [self scheduleInRunLoop: [NSRunLoop currentRunLoop] + forMode: NSDefaultRunLoopMode]; + } + + [service->runloop addTimer: service->timer + forMode: service->runloopmode]; + + [service->timer fire]; + } + else // notify the delegate of the error + { + if (YES == service->isPublishing) + { + [self netService: self + didNotPublish: CreateError(self, err)]; + } + else + { + [self netService: self + didNotResolve: CreateError(self, err)]; + } + } + } + UNLOCK(service); +} + +/** + * Description forthcoming + * + * + */ + +- (void) cleanup +{ + Service *service; + + INTERNALTRACE; + + service = (Service *) _reserved; + + LOCK(service); + { + if (service->runloop) + { + [self removeFromRunLoop: service->runloop + forMode: service->runloopmode]; + } + + if (service->timer) + { + [service->timer invalidate]; + DESTROY(service->timer); + } + + if (_netService) + { + DNSServiceRefDeallocate(_netService); + _netService = NULL; + } + + [service->info removeAllObjects]; + [service->foundAddresses removeAllObjects]; + } + UNLOCK(service); +} + +/** + * Description forthcoming + * + * + */ + +- (void) stopResolving: (id) sender +{ + Service *service; + + INTERNALTRACE; + + service = (Service *) _reserved; + + LOCK(service); + { + [service->timeout invalidate]; + [service->timer invalidate]; + + [self netService: self + didNotResolve: CreateError(self, NSNetServicesTimeoutError)]; + } + UNLOCK(service); +} + +/** + * Description forthcoming + * + * + */ + +- (void) resolverCallback: (DNSServiceRef) sdRef + flags: (DNSServiceFlags) flags + interface: (uint32_t) interfaceIndex + error: (DNSServiceErrorType) errorCode + fullname: (const char *) fullname + target: (const char *) hosttarget + port: (uint16_t) port + length: (uint16_t) txtLen + record: (const char *) txtRecord +{ + Service *service; + + INTERNALTRACE; + + service = (Service *) _reserved; + + LOCK(service); + + if (_netService) + { + if (errorCode) + { + [self cleanup]; + + [self netService: self + didNotResolve: CreateError(self, errorCode)]; + } + else + { + NSData *txt = nil; + NSString *target = nil; + + // Add the TXT record + txt = txtRecord + ? [[NSData alloc] initWithBytes: txtRecord length: txtLen] + : nil; + + // Get the host + target = hosttarget + ? [[NSString alloc] initWithUTF8String: hosttarget] + : nil; + + // Add the port + service->port = ntohs(port); + + // Remove the old TXT entry + [service->info removeObjectForKey: @"TXT"]; + + if (txt) + { + [service->info setObject: txt forKey: @"TXT"]; + [txt release]; + } + + // Remove the old host entry + [service->info removeObjectForKey: @"Host"]; + + // Add the host if there is one + if (target) + { + [service->info setObject: target forKey: @"Host"]; + [target release]; + } + + /* Add the interface so all subsequent + * queries are on the same interface + */ + service->interfaceIndex = interfaceIndex; + + service->timer = nil; + + // Prepare query for A and/or AAAA record + errorCode = DNSServiceQueryRecord((DNSServiceRef *) &_netService, + flags, + interfaceIndex, + hosttarget, + kDNSServiceType_ANY, + kDNSServiceClass_IN, + QueryCallback, + self); + + // No error? Then create a new timer + if (kDNSServiceErr_NoError == errorCode) + { + service->timer = [NSTimer timerWithTimeInterval: INTERVAL + target: self + selector: @selector(loop:) + userInfo: nil + repeats: YES]; + [service->timer fire]; + } + } + } + UNLOCK(service); +} + +/** + * Description forthcoming + * + * + */ + +- (BOOL) addAddress: (char *) addressString +{ + Service *service; + NSString *string; + + INTERNALTRACE; + + service = (Service *) _reserved; + + if (nil == service->foundAddresses) + { + service->foundAddresses = [[NSMutableArray alloc] init]; + } + + string = [NSString stringWithCString: addressString]; + if ([service->foundAddresses containsObject: string]) + { + // duplicate, didn't add it + return NO; + } + + [service->foundAddresses addObject: string]; + + return YES; +} + + +/** + * Description forthcoming + * + * + */ + +- (void) addAddress: (const void *) rdata + length: (uint16_t) rdlen + type: (uint16_t) rrtype + interface: (uint32_t) interfaceIndex +{ + Service *service; + + INTERNALTRACE; + + service = (Service *) _reserved; + + LOCK(service); + { + NSData *data = nil; + NSMutableArray *addresses = nil; + struct sockaddr *address = { 0 }; + size_t length = 0; + const unsigned char *rd = rdata; + char rdb[INET6_ADDRSTRLEN]; + + memset(rdb, 0, sizeof rdb); + + addresses = [service->info objectForKey: @"Addresses"]; + + if (nil == addresses) + { + addresses = [[NSMutableArray alloc] initWithCapacity: 1]; + } + + switch(rrtype) + { + case kDNSServiceType_A: // AF_INET + { + struct sockaddr_in ip4; + + // oogly + sprintf(rdb, "%d.%d.%d.%d", rd[0], rd[1], rd[2], rd[3]); + LOG(@"Found IPv4 <%s> on port %d", rdb, service->port); + + length = sizeof (struct sockaddr_in); + memset(&ip4, 0, length); + + inet_pton(AF_INET, rdb, &ip4.sin_addr); + ip4.sin_family = AF_INET; + ip4.sin_port = htons(service->port); + + address = (struct sockaddr *) &ip4; + } + break; + + #if defined(AF_INET6) + case kDNSServiceType_AAAA: // AF_INET6 + case kDNSServiceType_A6: // deprecates AAAA + { + struct sockaddr_in6 ip6; + + // Even more oogly + sprintf(rdb, "%x%x:%x%x:%x%x:%x%x:%x%x:%x%x:%x%x:%x%x", + rd[0], rd[1], rd[2], rd[3], + rd[4], rd[5], rd[6], rd[7], + rd[8], rd[9], rd[10], rd[11], + rd[12], rd[13], rd[14], rd[15]); + LOG(@"Found IPv6 <%s> on port %d", rdb, service->port); + + length = sizeof (struct sockaddr_in6); + memset(&ip6, 0, length); + + inet_pton(AF_INET6, rdb, &ip6.sin6_addr); +#if defined(HAVE_SA_LEN) + ip6.sin6_len = sizeof ip6; +#endif + ip6.sin6_family = AF_INET6; + ip6.sin6_port = htons(service->port); + ip6.sin6_flowinfo = 0; + ip6.sin6_scope_id = interfaceIndex; + + address = (struct sockaddr *) &ip6; + } + break; +#endif /* AF_INET6 */ + + default: + LOG(@"Unkown type of length <%d>", rdlen); + break; + } + + // check for duplicate entries + if ([self addAddress: rdb]) + { + // add it + data = [NSData dataWithBytes: address + length: length]; + + [addresses addObject: data]; + [service->info setObject: [addresses retain] + forKey: @"Addresses"]; + + // notify the delegate + [self netServiceDidResolveAddress: self]; + + [addresses release]; + + // got it, so invalidate the timeout + [service->timeout invalidate]; + service->timeout = nil; + } + } + UNLOCK(service); +} + +/** + * Description forthcoming + * + * + */ + +- (void) queryCallback: (DNSServiceRef) sdRef + flags: (DNSServiceFlags) flags + interface: (uint32_t) interfaceIndex + error: (DNSServiceErrorType) errorCode + fullname: (const char *) fullname + type: (uint16_t) rrtype + class: (uint16_t) rrclass + length: (uint16_t) rdlen + data: (const void *) rdata + ttl: (uint32_t) ttl +{ + Service *service; + + INTERNALTRACE; + + service = (Service *) _reserved; + + LOCK(service); + + if (_netService) + { + if (errorCode) + { + [self cleanup]; + + [self netService: self + didNotResolve: CreateError(self, errorCode)]; + + UNLOCK(service); + + return; + } + + switch(rrtype) + { + case kDNSServiceType_A: // 1 -- AF_INET + [self addAddress: rdata + length: rdlen + type: rrtype + interface: interfaceIndex]; + break; + + case kDNSServiceType_NS: + case kDNSServiceType_MD: + case kDNSServiceType_MF: + case kDNSServiceType_CNAME: // 5 + case kDNSServiceType_SOA: + case kDNSServiceType_MB: + case kDNSServiceType_MG: + case kDNSServiceType_MR: + case kDNSServiceType_NULL: // 10 + case kDNSServiceType_WKS: + case kDNSServiceType_PTR: + case kDNSServiceType_HINFO: + case kDNSServiceType_MINFO: + case kDNSServiceType_MX: // 15 + // not handled (yet) + break; + + case kDNSServiceType_TXT: + { + NSData + *data = nil; + + data = [NSData dataWithBytes: rdata + length: rdlen]; + + [service->info removeObjectForKey: @"TXT"]; + [service->info setObject: data + forKey: @"TXT"]; + + [self netService: self + didUpdateTXTRecordData: data]; + + } + break; + + case kDNSServiceType_RP: + case kDNSServiceType_AFSDB: + case kDNSServiceType_X25: + case kDNSServiceType_ISDN: // 20 + case kDNSServiceType_RT: + case kDNSServiceType_NSAP: + case kDNSServiceType_NSAP_PTR: + case kDNSServiceType_SIG: + case kDNSServiceType_KEY: // 25 + case kDNSServiceType_PX: + case kDNSServiceType_GPOS: + // not handled (yet) + break; + + case kDNSServiceType_AAAA: // 28 -- AF_INET6 + [self addAddress: rdata + length: rdlen + type: rrtype + interface: interfaceIndex]; + break; + + case kDNSServiceType_LOC: + case kDNSServiceType_NXT: // 30 + case kDNSServiceType_EID: + case kDNSServiceType_NIMLOC: + case kDNSServiceType_SRV: + case kDNSServiceType_ATMA: + case kDNSServiceType_NAPTR: // 35 + case kDNSServiceType_KX: + case kDNSServiceType_CERT: + // not handled (yet) + break; + + case kDNSServiceType_A6: // 38 -- AF_INET6, deprecates AAAA + [self addAddress: rdata + length: rdlen + type: rrtype + interface: interfaceIndex]; + break; + + case kDNSServiceType_DNAME: + case kDNSServiceType_SINK: // 40 + case kDNSServiceType_OPT: + // not handled (yet) + break; + + case kDNSServiceType_TKEY: // 249 + case kDNSServiceType_TSIG: // 250 + case kDNSServiceType_IXFR: + case kDNSServiceType_AXFR: + case kDNSServiceType_MAILB: + case kDNSServiceType_MAILA: + // not handled (yet) + break; + + case kDNSServiceType_ANY: + LOG(@"Oops, got the wildcard match..."); + break; + + default: + LOG(@"Don't know how to handle rrtype <%d>", rrtype); + break; + } + } + UNLOCK(service); +} + +/** + * Description forthcoming + * + * + */ + +- (void) registerCallback: (DNSServiceRef) sdRef + flags: (DNSServiceFlags) flags + error: (DNSServiceErrorType) errorCode + name: (const char *) name + type: (const char *) regtype + domain: (const char *) domain +{ + Service *service; + + INTERNALTRACE; + + service = (Service *) _reserved; + + LOCK(service); + + if (_netService) + { + if (errorCode) + { + [self cleanup]; + + [self netService: self + didNotPublish: CreateError(self, errorCode)]; + } + else + { + [self netServiceDidPublish: self]; + } + } + UNLOCK(service); +} + +/** + * Description forthcoming + * + * + */ + +- (void) loop: (id) sender +{ + int sock = 0; + struct timeval tout = { 0 }; + fd_set set; + DNSServiceErrorType err = kDNSServiceErr_NoError; + + sock = DNSServiceRefSockFD(_netService); + + if (-1 != sock) + { + FD_ZERO(&set); + FD_SET(sock, &set); + + if (1 == select(sock + 1, &set, (fd_set *) NULL, (fd_set *) NULL, &tout)) + { + err = DNSServiceProcessResult(_netService); + } + } + + if (kDNSServiceErr_NoError != err) + { + Service *service; + + service = (Service *) _reserved; + + if (YES == service->isPublishing) + { + [self netService: self + didNotPublish: CreateError(self, err)]; + } + else + { + [self netService: self + didNotResolve: CreateError(self, err)]; + } + } +} + +/** + * Converts txtDictionary into a TXT data. + * + * + */ + ++ (NSData *) dataFromTXTRecordDictionary: (NSDictionary *) txtDictionary +{ + NSMutableData *result = nil; + NSArray *keys = nil; + NSArray *values = nil; + int count = 0; + + INTERNALTRACE; + + count = [txtDictionary count]; + + if (count) + { + keys = [txtDictionary allKeys]; + values = [txtDictionary allValues]; + + if (keys && values) + { + TXTRecordRef txt; + int i = 0; + char key[256]; + + TXTRecordCreate(&txt, 0, NULL); + + for(; i < count; i++) + { + int length = 0; + int used = 0; + DNSServiceErrorType err = kDNSServiceErr_Unknown; + + if (! [[keys objectAtIndex: i] isKindOfClass: [NSString class]]) + { + LOG(@"%@ is not a string", [keys objectAtIndex: i]); + break; + } + + length = [[keys objectAtIndex: i] length]; + [[keys objectAtIndex: i] getCString: key + maxLength: sizeof key]; + used = strlen(key); + + if (! length || (used >= sizeof key)) + { + LOG(@"incorrect length %d - %d - %d", + length, used, sizeof key); + break; + } + + strcat(key, "\0"); + + if ([[values objectAtIndex: i] isKindOfClass: [NSString class]]) + { + char value[256]; + + length = [[values objectAtIndex: i] length]; + [[values objectAtIndex: i] getCString: value + maxLength: sizeof value]; + used = strlen(value); + + if (used >= sizeof value) + { + LOG(@"incorrect length %d - %d - %d", + length, used, sizeof value); + break; + } + + err = TXTRecordSetValue(&txt, + (const char *) key, + used, + value); + } + else if ([[values objectAtIndex: i] isKindOfClass: [NSData class]] + && [[values objectAtIndex: i] length] < 256 + && [[values objectAtIndex: i] length] >= 0) + { + err = TXTRecordSetValue(&txt, + (const char *) key, + [[values objectAtIndex: i] length], + [[values objectAtIndex: i] bytes]); + } + else if ([values objectAtIndex: i] == [NSNull null]) + { + err = TXTRecordSetValue(&txt, + (const char *) key, + 0, + NULL); + } + else + { + LOG(@"unknown value type"); + break; + } + + if (err != kDNSServiceErr_NoError) + { + LOG(@"error creating data type"); + break; + } + } + + if (i == count) + { + result = [NSData dataWithBytes: TXTRecordGetBytesPtr(&txt) + length: TXTRecordGetLength(&txt)]; + } + + TXTRecordDeallocate(&txt); + } + else + { + LOG(@"No keys or values"); + } + + // both are autorelease'd + keys = nil; + values = nil; + } + else + { + LOG(@"Dictionary seems empty"); + } + return result; +} + +/** + * Converts the TXT data txtData into a dictionary. + * + * + */ + ++ (NSDictionary *) dictionaryFromTXTRecordData: (NSData *) txtData +{ + NSMutableDictionary *result = nil; + int len = 0; + const void *txt = 0; + + INTERNALTRACE; + + len = [txtData length]; + txt = [txtData bytes]; + + // + // A TXT record cannot exceed 65535 bytes, see Chapter 6.1 of + // http://files.dns-sd.org/draft-cheshire-dnsext-dns-sd.txt + // + if ((len > 0) && (len < 65536)) + { + uint16_t i = 0; + uint16_t count = 0; + + // get number of keys + count = TXTRecordGetCount(len, txt); + result = [NSMutableDictionary dictionaryWithCapacity: 1]; + + if (result) + { + // go through all keys + for(; i < count; i++) + { + char key[256]; + uint8_t valLen = 0; + const void *value = NULL; + DNSServiceErrorType err = kDNSServiceErr_NoError; + + err = TXTRecordGetItemAtIndex(len, txt, i, + sizeof key, key, + &valLen, &value); + + // only if we can get the key and value... + if (kDNSServiceErr_NoError == err) + { + NSData *data = nil; + NSString *str = nil; + + str = [NSString stringWithUTF8String: key]; + + if (value) + { + data = [NSData dataWithBytes: value + length: valLen]; + } + + if (data && str && [str length] + && ! [result objectForKey: str]) + { + /* only add if key and value were created + * and key doesn't exist yet + */ + [result setValue: data + forKey: str]; + } + else + { + /* I'm not exactly sure what to do if there + * is a key WITHOUT a value + * Theoretically '<6>foobar' should be identical + * to '<7>foobar=' i.e. the value would be [NSNull null] + */ + [result setValue: [NSNull null] + forKey: str]; + } + + // both are autorelease'd + data = nil; + str = nil; + } + else + { + LOG(@"Couldn't get TXTRecord item"); + } + } + } + else + { + LOG(@"Couldn't create dictionary"); + } + } + else + { + LOG(@"TXT record has incorrect length: <%d>", len); + } + return result; +} + +/** + * Initializes the receiver for service resolution. Use this method to create + * an object if you intend to -resolve a service. + * + */ + +- (id) initWithDomain: (NSString *) domain + type: (NSString *) type + name: (NSString *) name +{ + INTERNALTRACE; + + return [self initWithDomain: domain + type: type + name: name + port: -1]; // -1 to indicate resolution, not publish +} + +/** + * Initializes the receiver for service publication. Use this method to create + * an object if you intend to -publish a service. + * + */ + +- (id) initWithDomain: (NSString *) domain + type: (NSString *) type + name: (NSString *) name + port: (int) port +{ + INTERNALTRACE; + + if ((self = [super init])) + { + Service *service; + + service = malloc(sizeof (struct _Service)); + memset(service, 0, sizeof service); + + CREATELOCK(service); + + service->runloop = nil; + service->runloopmode = nil; + service->timer = nil; + service->timeout = nil; + + service->info = [[NSMutableDictionary alloc] initWithCapacity: 1]; + [service->info setObject: [domain retain] + forKey: @"Domain"]; + [service->info setObject: [name retain] + forKey: @"Name"]; + [service->info setObject: [type retain] + forKey: @"Type"]; + + service->foundAddresses = nil; + + service->interfaceIndex = 0; + service->port = htons(port); + + service->monitor = nil; + + service->isPublishing = (-1 == port) ? NO : YES; + service->isMonitoring = NO; + + _netService = NULL; + _delegate = nil; + _reserved = service; + + return self; + } + + return nil; +} + +/** + * Removes the service from the specified run loop. + * + * + */ + +- (void) removeFromRunLoop: (NSRunLoop *) aRunLoop + forMode: (NSString *) mode +{ + Service *service; + + INTERNALTRACE; + + service = (Service *) _reserved; + + LOCK(service); + { + if (service->timer) + { + [service->timer setFireDate: [NSDate date]]; + [service->timer invalidate]; + + // Do not release the timer! + service->timer = nil; + } + + // Do not release the runloop! + service->runloop = nil; + + DESTROY(service->runloopmode); + } + UNLOCK(service); +} + +/** + * Adds the service to the specified run loop. + * + * + */ + +- (void) scheduleInRunLoop: (NSRunLoop *) aRunLoop + forMode: (NSString *) mode +{ + Service *service; + + INTERNALTRACE; + + service = (Service *) _reserved; + + LOCK(service); + { + if (service->timer) + { + [service->timer setFireDate: [NSDate date]]; + [service->timer invalidate]; + service->timer = nil; + } + + service->timer = [NSTimer timerWithTimeInterval: INTERVAL + target: self + selector: @selector(loop:) + userInfo: nil + repeats: YES]; + + service->runloop = aRunLoop; + service->runloopmode = mode; + + [service->timer retain]; + } + UNLOCK(service); +} + +/** + * Attempts to publish a service on the network. + * + * + */ + +- (void) publish +{ + Service *service; + DNSServiceErrorType err = kDNSServiceErr_NoError; + DNSServiceFlags flags = 0; + + INTERNALTRACE; + + service = (Service *) _reserved; + + LOCK(service); + { + do + { + // cannot -publish on a service that's init'd for resolving + if (NO == service->isPublishing) + { + err = NSNetServicesBadArgumentError; + break; + } + + if (! _delegate) + { + err = NSNetServicesInvalidError; + break; + } + + if (service->timer) + { + err = NSNetServicesActivityInProgress; + break; + } + + if (service->timeout) + { + [service->timeout setFireDate: [NSDate date]]; + [service->timeout invalidate]; + service->timeout = nil; + } + + err = DNSServiceRegister((DNSServiceRef *) &_netService, + flags, service->interfaceIndex, + [[service->info objectForKey: @"Name"] UTF8String], + [[service->info objectForKey: @"Type"] UTF8String], + [[service->info objectForKey: @"Domain"] UTF8String], + NULL, service->port, 0, NULL, + RegistrationCallback, self); + } + while(0); + } + UNLOCK(service); + + [self executeWithError: err]; +} + +/** + * This method is deprecated. Use -resolveWithTimeout: instead. + * + * + */ + +- (void) resolve +{ + INTERNALTRACE; + + [self resolveWithTimeout: 5]; +} + +/** + * Starts a service resolution for a limited duration. + * + * + */ + +- (void) resolveWithTimeout: (NSTimeInterval) timeout +{ + Service *service; + DNSServiceErrorType err = kDNSServiceErr_NoError; + DNSServiceFlags flags = 0; + + INTERNALTRACE; + + service = (Service *) _reserved; + + LOCK(service); + { + do + { + // cannot -resolve on a service that's init'd for publishing + if (YES == service->isPublishing) + { + err = NSNetServicesBadArgumentError; + break; + } + + if (! _delegate) + { + err = NSNetServicesInvalidError; + break; + } + + if (service->timer) + { + err = NSNetServicesActivityInProgress; + break; + } + + if (service->timeout) + { + [service->timeout setFireDate: [NSDate date]]; + [service->timeout invalidate]; + service->timeout = nil; + } + + service->timeout = [NSTimer alloc]; + { + NSDate *date = nil; + + date = [NSDate dateWithTimeIntervalSinceNow: timeout + SHORTTIMEOUT]; + + [service->timeout initWithFireDate: date + interval: INTERVAL + target: self + selector: @selector(stopResolving:) + userInfo: nil + repeats: NO]; + } + + err = DNSServiceResolve((DNSServiceRef *) &_netService, + flags, + service->interfaceIndex, + [[service->info objectForKey: @"Name"] UTF8String], + [[service->info objectForKey: @"Type"] UTF8String], + [[service->info objectForKey: @"Domain"] UTF8String], + ResolverCallback, + self); + } + while(0); + } + UNLOCK(service); + + [self executeWithError: err]; +} + +/** + * Stops the current attempt to publish or resolve a service. + * + * + */ + +- (void) stop +{ + Service *service; + + INTERNALTRACE; + + service = (Service *) _reserved; + + LOCK(service); + { + [self cleanup]; + + [self netServiceDidStop: self]; + } + UNLOCK(service); +} + +/** + * Starts monitoring of TXT record updates. + * + * + */ + +- (void) startMonitoring +{ + Service *service; + + INTERNALTRACE; + + service = (Service *) _reserved; + + LOCK(service); + { + // Obviously this will only work on a resolver + if (! service->isPublishing) + { + if (! service->isMonitoring) + { + service->monitor + = [[NSNetServiceMonitor alloc] initWithDelegate: self]; + + [service->monitor scheduleInRunLoop: service->runloop + forMode: service->runloopmode]; + [service->monitor start]; + + service->isMonitoring = YES; + } + } + } + UNLOCK(service); +} + +/** + * Stops monitoring of TXT record updates. + * + * + */ + +- (void) stopMonitoring +{ + Service *service; + + INTERNALTRACE; + + service = (Service *) _reserved; + + LOCK(service); + { + if (! service->isPublishing) + { + if (service->isMonitoring) + { + [service->monitor stop]; + + // Probably don't need it anymore, so release it + DESTROY(service->monitor); + service->isMonitoring = NO; + } + } + } + UNLOCK(service); +} + +/** + * Returns the receiver's delegate. + * + * + */ + +- (id) delegate +{ + INTERNALTRACE; + + return [[_delegate retain] autorelease]; +} + +/** + * Sets the receiver's delegate. + * + * + */ + +- (void) setDelegate: (id) delegate +{ + INTERNALTRACE; + + ASSIGN(_delegate, delegate); +} + +/** + * Returns an array of NSData objects that each contain the socket address of + * the service. + * + */ + +- (NSArray *) addresses +{ + INTERNALTRACE; + + return [((Service*)_reserved)->info objectForKey: @"Addresses"]; +} + +/** + * Returns the domain name of the service. + * + * + */ + +- (NSString *) domain +{ + INTERNALTRACE; + + return [((Service*)_reserved)->info objectForKey: @"Domain"]; +} + +/** + * Returns the host name of the computer publishing the service. + * + * + */ + +- (NSString *) hostName +{ + INTERNALTRACE; + + return [((Service*)_reserved)->info objectForKey: @"Host"]; +} + +/** + * Returns the name of the service. + * + * + */ + +- (NSString *) name +{ + INTERNALTRACE; + + return [((Service*)_reserved)->info objectForKey: @"Name"]; +} + +/** + * Returns the type of the service. + * + * + */ + +- (NSString *) type +{ + INTERNALTRACE; + + return [((Service*)_reserved)->info objectForKey: @"Type"]; +} + +/** + * This method is deprecated. Use -TXTRecordData instead. + * + * + */ + +- (NSString *) protocolSpecificInformation +{ + NSMutableArray *array = nil; + Service *service; + + INTERNALTRACE; + + service = (Service *) _reserved; + + // + // I must admit, the following may not be entirely correct... + // + LOCK(service); + { + NSDictionary *dictionary = nil; + + dictionary = [NSNetService dictionaryFromTXTRecordData: + [self TXTRecordData]]; + + if (dictionary) + { + NSEnumerator *keys = nil; + NSString *key = nil; + + array = [NSMutableArray arrayWithCapacity: [dictionary count]]; + keys = [dictionary keyEnumerator]; + + while((key = [keys nextObject])) + { + NSData *value = nil; + + value = [dictionary objectForKey: key]; + + if (value != (NSData *) [NSNull null]) + { + NSData *str; + NSString *pair; + + // FIXME ... should this be UTF8? + str = [[NSString alloc] + initWithBytes: [value bytes] + length: [value length] + encoding: NSUTF8StringEncoding]; + pair = [NSString stringWithFormat: @"%@=%@", key, str]; + RELEASE(str); + + [array addObject: pair]; + } + else if ([key length]) + { + [array addObject: [NSString stringWithFormat: @"%@", key]]; + } + } + } + } + UNLOCK(service); + + return ([array count] ? [array componentsJoinedByString: @"\001"] + : (NSString *) nil); +} + +/** + * This method is deprecated. Use -setTXTRecordData: instead. + * + * + */ + +- (void) setProtocolSpecificInformation: (NSString *) specificInformation +{ + Service *service; + + INTERNALTRACE; + + service = (Service *) _reserved; + + // + // Again, the following may not be entirely correct... + // + LOCK(service); + { + NSArray *array = nil; + + array = [specificInformation componentsSeparatedByString: @"\001"]; + + if (array) + { + NSMutableDictionary *dictionary = nil; + NSEnumerator *enumerator = nil; + NSString *item = nil; + + dictionary + = [NSMutableDictionary dictionaryWithCapacity: [array count]]; + enumerator = [array objectEnumerator]; + + while((item = [enumerator nextObject])) + { + NSArray *parts = nil; + NSData *value; + + parts = [item componentsSeparatedByString:@"="]; + + value = [[parts objectAtIndex: 1] + dataUsingEncoding: NSUTF8StringEncoding]; + [dictionary setObject: value + forKey: [parts objectAtIndex: 0]]; + } + + [self setTXTRecordData: + [NSNetService dataFromTXTRecordDictionary: dictionary]]; + } + } + UNLOCK(service); +} + +/** + * Returns the TXT record. + * + * + */ + +- (NSData *) TXTRecordData +{ + INTERNALTRACE; + + return [((Service*)_reserved)->info objectForKey: @"TXT"]; +} + +/** + * Sets the TXT record. + * + * + */ + +- (BOOL) setTXTRecordData: (NSData *) recordData +{ + Service *service; + BOOL result = NO; + + INTERNALTRACE; + + service = (Service *) _reserved; + + LOCK(service); + { + // Not allowed on a resolver... + if (service->isPublishing) + { + DNSServiceErrorType + err = kDNSServiceErr_NoError; + + // Set the value, or remove it if empty + if (recordData) + { + [service->info setObject: recordData + forKey: @"TXT"]; + } + else + { + [service->info removeObjectForKey: @"TXT"]; + } + + // Assume it worked + result = YES; + + // Now update the record so others can pick it up + err = DNSServiceUpdateRecord(_netService, + NULL, + 0, + recordData ? [recordData length] : 0, + recordData ? [recordData bytes] : NULL, + 0); + if (err) + { + result = NO; + } + } + } + UNLOCK(service); + + return result; +} + +/** + * Retrieves the input and output stream for the receiver. + * + * + */ + +- (BOOL) getInputStream: (NSInputStream **) inputStream + outputStream: (NSOutputStream **) outputStream +{ + Service *service; + + INTERNALTRACE; + + service = (Service *) _reserved; + + LOCK(service); + { + [NSStream getStreamsToHost: [service->info objectForKey: @"Host"] + port: ntohs(service->port) + inputStream: inputStream + outputStream: outputStream]; + } + UNLOCK(service); + + return inputStream && outputStream; +} + +/** + * Description forthcoming + * + * + */ + +- (void) netServiceWillPublish: (NSNetService *) sender +{ + INTERNALTRACE; + + if ([_delegate respondsToSelector: @selector(netServiceWillPublish:)]) + { + [_delegate netServiceWillPublish: sender]; + } +} + +/** + * Description forthcoming + * + * + */ + +- (void) netServiceDidPublish: (NSNetService *) sender +{ + INTERNALTRACE; + + if ([_delegate respondsToSelector: @selector(netServiceDidPublish:)]) + { + [_delegate netServiceDidPublish: sender]; + } +} + +/** + * Description forthcoming + * + * + */ + +- (void) netService: (NSNetService *) sender + didNotPublish: (NSDictionary *) errorDict +{ + INTERNALTRACE; + + if ([_delegate respondsToSelector: @selector(netService:didNotPublish:)]) + { + [_delegate netService: sender + didNotPublish: errorDict]; + } +} + +/** + * Description forthcoming + * + * + */ + +- (void) netServiceWillResolve: (NSNetService *) sender +{ + INTERNALTRACE; + + if ([_delegate respondsToSelector: @selector(netServiceWillResolve:)]) + { + [_delegate netServiceWillResolve: sender]; + } +} + +/** + * Description forthcoming + * + * + */ + +- (void) netServiceDidResolveAddress: (NSNetService *) sender +{ + INTERNALTRACE; + + if ([_delegate respondsToSelector: @selector(netServiceDidResolveAddress:)]) + { + [_delegate netServiceDidResolveAddress: sender]; + } +} + +/** + * Description forthcoming + * + * + */ + +- (void) netService: (NSNetService *) sender + didNotResolve: (NSDictionary *) errorDict +{ + INTERNALTRACE; + + if ([_delegate respondsToSelector: @selector(netService:didNotResolve:)]) + { + [_delegate netService: sender + didNotResolve: errorDict]; + } +} + +/** + * Description forthcoming + * + * + */ + +- (void) netServiceDidStop: (NSNetService *) sender +{ + INTERNALTRACE; + + if ([_delegate respondsToSelector: @selector(netServiceDidStop:)]) + { + [_delegate netServiceDidStop: sender]; + } +} + +/** + * Description forthcoming + * + * + */ + +- (void) netService: (NSNetService *) sender + didUpdateTXTRecordData: (NSData *) data +{ + INTERNALTRACE; + + if ([_delegate respondsToSelector: + @selector(netService:didUpdateTXTRecordData:)]) + { + [_delegate netService: sender + didUpdateTXTRecordData: data]; + } +} + +/** + * Description forthcoming + * + * + */ + +- (void) netService: (NSNetService *) sender + didNotMonitor: (NSDictionary *) errorDict +{ + INTERNALTRACE; + + // This method is kind of a misnomer. It's called whenever NSNetMonitor + // encounters an error while monitoring. + // All we do is stop monitoring -- which we COULD do from NSNetMonitor + // directly, but this seems to be much cleaner. + + [self stopMonitoring]; +} + +/** + * Description forthcoming + * + * + */ + +- (id) init +{ + DESTROY(self); + return self; +} + +/** + * Description forthcoming + * + * + */ + +- (void) dealloc +{ + Service *service; + + INTERNALTRACE; + + service = (Service *) _reserved; + { + LOCK(service); + { + [self stopMonitoring]; + [self cleanup]; + + DESTROY(service->info); + DESTROY(service->foundAddresses); + DESTROY(_delegate); + } + UNLOCK(service); + + DESTROYLOCK(service); + + free(service); + } + [super dealloc]; +} + +@end + +@implementation NSNetServiceMonitor + +/** + * Description forthcoming + * + * + */ + ++ (void) initialize +{ + INTERNALTRACE; + + SETVERSION(NSNetServiceMonitor); +} + +/** + * Description forthcoming + * + * + */ + +- (void) loop: (id) sender +{ + int sock = 0; + struct timeval tout = { 0 }; + fd_set set; + DNSServiceErrorType err = kDNSServiceErr_NoError; + + sock = DNSServiceRefSockFD(_netServiceMonitor); + + if (-1 != sock) + { + FD_ZERO(&set); + FD_SET(sock, &set); + + if (1 == select(sock + 1, &set, (fd_set *) NULL, (fd_set *) NULL, &tout)) + { + err = DNSServiceProcessResult(_netServiceMonitor); + } + } + + if (kDNSServiceErr_NoError != err) + { + LOG(@"Error <%d> while monitoring", err); + + [_delegate netService: _delegate + didNotMonitor: CreateError(self, err)]; + } +} + +/** + * Description forthcoming + * + * + */ + +- (void) queryCallback: (DNSServiceRef) sdRef + flags: (DNSServiceFlags) flags + interface: (uint32_t) interfaceIndex + error: (DNSServiceErrorType) errorCode + fullname: (const char *) fullname + type: (uint16_t) rrtype + class: (uint16_t) rrclass + length: (uint16_t) rdlen + data: (const void *) rdata + ttl: (uint32_t) ttl +{ + Monitor *monitor; + + INTERNALTRACE; + + monitor = (Monitor *) _reserved; + + LOCK(monitor); + + if (_delegate) + { + // we are 'monitoring' kDNSServiceType_TXT + // this is already handled by the delegate's method of the same name + // so we simply pass this through + [_delegate queryCallback: sdRef + flags: flags + interface: interfaceIndex + error: errorCode + fullname: fullname + type: rrtype + class: rrclass + length: rdlen + data: rdata + ttl: ttl]; + } + UNLOCK(monitor); +} + +/** + * Description forthcoming + * + * + */ + +- (id) initWithDelegate: (id) delegate +{ + INTERNALTRACE; + + if ((self = [super init]) != nil) + { + Monitor *monitor; + + monitor = malloc(sizeof (struct _Monitor)); + memset(monitor, 0, sizeof monitor); + + CREATELOCK(monitor); + + monitor->runloop = nil; + monitor->runloopmode = nil; + monitor->timer = nil; + + _netServiceMonitor = NULL; + _delegate = [delegate retain]; + _reserved = monitor; + } + return self; +} + +/** + * Description forthcoming + * + * + */ + +- (void) removeFromRunLoop: (NSRunLoop *) aRunLoop + forMode: (NSString *) mode +{ + Monitor *monitor; + + INTERNALTRACE; + + monitor = (Monitor *) _reserved; + + LOCK(monitor); + { + if (monitor->timer) + { + [monitor->timer setFireDate: [NSDate date]]; + [monitor->timer invalidate]; + monitor->timer = nil; + } + + // Do not release the runloop! + monitor->runloop = nil; + + // [monitor->runloopmode release]; + monitor->runloopmode = nil; + } + UNLOCK(monitor); +} + +/** + * Description forthcoming + * + * + */ + +- (void) scheduleInRunLoop: (NSRunLoop *) aRunLoop + forMode: (NSString *) mode +{ + Monitor *monitor; + + INTERNALTRACE; + + monitor = (Monitor *) _reserved; + + LOCK(monitor); + { + if (monitor->timer) + { + [monitor->timer setFireDate: [NSDate date]]; + [monitor->timer invalidate]; + monitor->timer = nil; + } + + monitor->runloop = aRunLoop; + monitor->runloopmode = mode; + } + UNLOCK(monitor); +} + +/** + * Description forthcoming + * + * + */ + +- (void) start +{ + Monitor *monitor; + + INTERNALTRACE; + + monitor = (Monitor *) _reserved; + + LOCK(monitor); + { + DNSServiceErrorType err = kDNSServiceErr_NoError; + DNSServiceFlags flags = kDNSServiceFlagsLongLivedQuery; + NSString *fullname = nil; + + do + { + if (! _delegate) + { + err = NSNetServicesInvalidError; + break; + } + + if (monitor->timer) + { + err = NSNetServicesActivityInProgress; + break; + } + + fullname = [NSString stringWithFormat: @"%@.%@%@", + [_delegate name], [_delegate type], [_delegate domain]]; + + err = DNSServiceQueryRecord((DNSServiceRef *) &_netServiceMonitor, + flags, + 0, + [fullname UTF8String], + kDNSServiceType_TXT, + kDNSServiceClass_IN, + QueryCallback, + self); + + if (kDNSServiceErr_NoError == err) + { + monitor->timer = [NSTimer timerWithTimeInterval: INTERVAL + target: self + selector: @selector(loop:) + userInfo: nil + repeats: YES]; + + [monitor->runloop addTimer: monitor->timer + forMode: monitor->runloopmode]; + + [monitor->timer fire]; + } + } + while(0); + } + UNLOCK(monitor); +} + +/** + * Description forthcoming + * + * + */ + +- (void) stop +{ + Monitor *monitor; + + INTERNALTRACE; + + monitor = (Monitor *) _reserved; + + LOCK(monitor); + { + if (monitor->runloop) + { + [self removeFromRunLoop: monitor->runloop + forMode: monitor->runloopmode]; + } + + if (monitor->timer) + { + [monitor->timer invalidate]; + monitor->timer = nil; + } + + if (_netServiceMonitor) + { + DNSServiceRefDeallocate(_netServiceMonitor); + _netServiceMonitor = NULL; + } + } + UNLOCK(monitor); +} + +/** + * Description forthcoming + * + * + */ + +- (id) init +{ + DESTROY(self); + return nil; +} + +/** + * Description forthcoming + * + * + */ + +- (void) dealloc +{ + Monitor *monitor; + + INTERNALTRACE; + + monitor = (Monitor *) _reserved; + { + LOCK(monitor); + { + [self stop]; + + _delegate = nil; + } + UNLOCK(monitor); + + DESTROYLOCK(monitor); + + free(monitor); + } + [super dealloc]; +} + +@end + +/** + * Description forthcoming + * + * + */ + +static NSDictionary * +CreateError(id sender, int errorCode) +{ + NSMutableDictionary *dictionary = nil; + int error = 0; + + INTERNALTRACE; + + dictionary = [NSMutableDictionary dictionary]; + error = ConvertError(errorCode); + + LOG(@"%@ says error <%d> - <%d>", [sender description], errorCode, error); + + [dictionary setObject: [NSNumber numberWithInt: error] + forKey: NSNetServicesErrorCode]; + [dictionary setObject: sender + forKey: NSNetServicesErrorDomain]; + + return dictionary; // autorelease'd +} + +/** + * Description forthcoming + * + * + */ + +static int +ConvertError(int errorCode) +{ + INTERNALTRACE; + + switch(errorCode) + { + case kDNSServiceErr_Unknown: + return NSNetServicesUnknownError; + + case kDNSServiceErr_NoSuchName: + return NSNetServicesNotFoundError; + + case kDNSServiceErr_NoMemory: + return NSNetServicesUnknownError; + + case kDNSServiceErr_BadParam: + case kDNSServiceErr_BadReference: + case kDNSServiceErr_BadState: + case kDNSServiceErr_BadFlags: + return NSNetServicesBadArgumentError; + + case kDNSServiceErr_Unsupported: + return NSNetServicesUnknownError; + + case kDNSServiceErr_NotInitialized: + return NSNetServicesInvalidError; + + case kDNSServiceErr_AlreadyRegistered: + case kDNSServiceErr_NameConflict: + return NSNetServicesCollisionError; + + case kDNSServiceErr_Invalid: + return NSNetServicesInvalidError; + + case kDNSServiceErr_Firewall: + return NSNetServicesUnknownError; + + case kDNSServiceErr_Incompatible: + // The client library is incompatible with the daemon + return NSNetServicesInvalidError; + + case kDNSServiceErr_BadInterfaceIndex: + case kDNSServiceErr_Refused: + return NSNetServicesUnknownError; + + case kDNSServiceErr_NoSuchRecord: + case kDNSServiceErr_NoAuth: + case kDNSServiceErr_NoSuchKey: + return NSNetServicesNotFoundError; + + case kDNSServiceErr_NATTraversal: + case kDNSServiceErr_DoubleNAT: + case kDNSServiceErr_BadTime: + return NSNetServicesUnknownError; + } + + return errorCode; +} + +/** + * Description forthcoming + * + * + */ + +static void +EnumerationCallback(DNSServiceRef sdRef, + DNSServiceFlags flags, + uint32_t interfaceIndex, + DNSServiceErrorType errorCode, + const char *replyDomain, + void *context) +{ + // NSNetServiceBrowser + [(id) context enumCallback: sdRef + flags: flags + interface: interfaceIndex + error: errorCode + domain: replyDomain]; +} + +/** + * Description forthcoming + * + * + */ + +static void +BrowserCallback(DNSServiceRef sdRef, + DNSServiceFlags flags, + uint32_t interfaceIndex, + DNSServiceErrorType errorCode, + const char *replyName, + const char *replyType, + const char *replyDomain, + void *context) +{ + // NSNetServiceBrowser + [(id) context browseCallback: sdRef + flags: flags + interface: interfaceIndex + error: errorCode + name: replyName + type: replyType + domain: replyDomain]; +} + +/** + * Description forthcoming + * + * + */ + +static void +ResolverCallback(DNSServiceRef sdRef, + DNSServiceFlags flags, + uint32_t interfaceIndex, + DNSServiceErrorType errorCode, + const char *fullname, + const char *hosttarget, + uint16_t port, + uint16_t txtLen, + const char *txtRecord, + void *context) +{ + // NSNetService + [(id) context resolverCallback: sdRef + flags: flags + interface: interfaceIndex + error: errorCode + fullname: fullname + target: hosttarget + port: port + length: txtLen + record: txtRecord]; +} + +/** + * Description forthcoming + * + * + */ + +static void +RegistrationCallback(DNSServiceRef sdRef, + DNSServiceFlags flags, + DNSServiceErrorType errorCode, + const char *name, + const char *regtype, + const char *domain, + void *context) +{ + // NSNetService + [(id) context registerCallback: sdRef + flags: flags + error: errorCode + name: name + type: regtype + domain: domain]; +} + +/** + * Description forthcoming + * + * + */ + +static void +QueryCallback(DNSServiceRef sdRef, + DNSServiceFlags flags, + uint32_t interfaceIndex, + DNSServiceErrorType errorCode, + const char *fullname, + uint16_t rrtype, + uint16_t rrclass, + uint16_t rdlen, + const void *rdata, + uint32_t ttl, + void *context) +{ + // NSNetService, NSNetServiceMonitor + [(id) context queryCallback: sdRef + flags: flags + interface: interfaceIndex + error: errorCode + fullname: fullname + type: rrtype + class: rrclass + length: rdlen + data: rdata + ttl: ttl]; +} + diff --git a/Source/NSNotification.m b/Source/NSNotification.m index 28051341a..ff1d7d0ef 100644 --- a/Source/NSNotification.m +++ b/Source/NSNotification.m @@ -18,7 +18,8 @@ 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., 51 Franklin Street, Fifth Floor, Boston, MA 02111 USA. + Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02111 USA. NSNotification class reference $Date$ $Revision$ diff --git a/Source/NSNotificationCenter.m b/Source/NSNotificationCenter.m index 63a9a870d..64f4df3d2 100644 --- a/Source/NSNotificationCenter.m +++ b/Source/NSNotificationCenter.m @@ -22,8 +22,8 @@ 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., 51 Franklin Street, Fifth Floor, Boston, - MA 02111 USA. + Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02111 USA. NSNotificationCenter class reference $Date$ $Revision$ @@ -241,12 +241,10 @@ typedef struct NCTbl { GSIMapTable named; /* Getting named messages only. */ unsigned lockCount; /* Count recursive operations. */ GSLazyRecursiveLock *_lock; /* Lock out other threads. */ - BOOL lockingDisabled; - - Observation *freeList; - Observation **chunks; - unsigned numChunks; - GSIMapTable cache[CACHESIZE]; + Observation *freeList; + Observation **chunks; + unsigned numChunks; + GSIMapTable cache[CACHESIZE]; unsigned short chunkIndex; unsigned short cacheIndex; } NCTable; @@ -407,16 +405,14 @@ static NCTable *newNCTable(void) static inline void lockNCTable(NCTable* t) { - if (t->lockingDisabled == NO) - [t->_lock lock]; + [t->_lock lock]; t->lockCount++; } static inline void unlockNCTable(NCTable* t) { t->lockCount--; - if (t->lockingDisabled == NO) - [t->_lock unlock]; + [t->_lock unlock]; } static void obsFree(Observation *o) @@ -1142,32 +1138,3 @@ static NSNotificationCenter *default_center = nil; @end -@implementation NSNotificationCenter (GNUstep) - -- (BOOL) setLockingDisabled: (BOOL)flag -{ - BOOL old; - - GSOnceMLog(@"This method is deprecated"); - lockNCTable(TABLE); - if (self == default_center) - { - unlockNCTable(TABLE); - [NSException raise: NSInvalidArgumentException - format: @"Can't change locking of default center."]; - } - if (LOCKCOUNT > 1) - { - unlockNCTable(TABLE); - [NSException raise: NSInvalidArgumentException - format: @"Can't change locking during post."]; - } - - old = TABLE->lockingDisabled; - TABLE->lockingDisabled = flag; - unlockNCTable(TABLE); - return old; -} - -@end - diff --git a/Source/NSNotificationQueue.m b/Source/NSNotificationQueue.m index 7b2069eb7..6ea8d13de 100644 --- a/Source/NSNotificationQueue.m +++ b/Source/NSNotificationQueue.m @@ -38,6 +38,7 @@ #include "Foundation/NSString.h" #include "Foundation/NSThread.h" +#include "GSPrivate.h" /* NotificationQueueList by Richard Frith-Macdonald These objects are used to maintain lists of NSNotificationQueue objects. There is one list per NSThread, with the first object in the list stored @@ -574,7 +575,7 @@ static inline void notifyASAP(NSNotificationQueue *q) } void -GSNotifyASAP() +GSPrivateNotifyASAP() { NotificationQueueList *item; @@ -613,7 +614,7 @@ static inline void notifyIdle(NSNotificationQueue *q) } void -GSNotifyIdle() +GSPrivateNotifyIdle() { NotificationQueueList *item; @@ -627,7 +628,7 @@ GSNotifyIdle() } BOOL -GSNotifyMore() +GSPrivateNotifyMore() { NotificationQueueList *item; diff --git a/Source/NSNull.m b/Source/NSNull.m index 697093d3a..e432e07a9 100644 --- a/Source/NSNull.m +++ b/Source/NSNull.m @@ -18,8 +18,8 @@ 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., 51 Franklin Street, Fifth Floor, Boston, - MA 02111 USA. + Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02111 USA. NSNull class reference $Date$ $Revision$ diff --git a/Source/NSNumber.m b/Source/NSNumber.m index 0342b4ac2..9ea1b6f50 100644 --- a/Source/NSNumber.m +++ b/Source/NSNumber.m @@ -41,6 +41,7 @@ #include "Foundation/NSObjCRuntime.h" #include "NSConcreteNumber.h" +#include "GSPrivate.h" @interface GSCachedBool : NSBoolNumber @end @@ -152,7 +153,7 @@ GSNumberInfoFromObject(NSNumber *o) } unsigned int -GSSmallHash(int n) +GSPrivateSmallHash(int n) { return smallHashes[n + GS_SMALL]; } @@ -827,7 +828,7 @@ static Class doubleNumberClass; switch (info->typeLevel) { case 0: - return [self boolValue] ? @"YES" : @"NO"; + return [self boolValue] ? @"1" : @"0"; break; case 1: diff --git a/Source/NSNumberFormatter.m b/Source/NSNumberFormatter.m index 1b0d0ce1b..0a1a47ed3 100644 --- a/Source/NSNumberFormatter.m +++ b/Source/NSNumberFormatter.m @@ -20,7 +20,8 @@ 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., 51 Franklin Street, Fifth Floor, Boston, MA 02111 USA. + Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02111 USA. NSNumberFormatter class reference $Date$ $Revision$ @@ -33,7 +34,7 @@ #include "Foundation/NSNumberFormatter.h" #include "Foundation/NSString.h" #include "Foundation/NSUserDefaults.h" - +#include "Foundation/NSCharacterSet.h" @implementation NSNumberFormatter @@ -45,7 +46,8 @@ - (NSAttributedString*) attributedStringForObjectValue: (id)anObject withDefaultAttributes: (NSDictionary*)attr { - float val; + NSDecimalNumber *zeroNumber = [NSDecimalNumber zero]; + NSDecimalNumber *nanNumber = [NSDecimalNumber notANumber]; if (anObject == nil) { @@ -55,17 +57,22 @@ { return [self attributedStringForNotANumber]; } - else if ([anObject intValue] == 0) + else if ([anObject isEqual: nanNumber]) + { + return [self attributedStringForNotANumber]; + } + else if ([anObject isEqual: zeroNumber]) { return [self attributedStringForZero]; } - val = [anObject intValue]; - if ((val > 0) && (_attributesForPositiveValues)) + if (([(NSNumber*)anObject compare: zeroNumber] == NSOrderedDescending) + && (_attributesForPositiveValues)) { attr = _attributesForPositiveValues; } - else if ((val < 0) && (_attributesForNegativeValues)) + else if (([(NSNumber*)anObject compare: zeroNumber] == NSOrderedAscending) + && (_attributesForNegativeValues)) { attr = _attributesForNegativeValues; } @@ -187,10 +194,11 @@ if (range.length != 0) { string = AUTORELEASE([string mutableCopy]); - [(NSMutableString*)string replaceOccurrencesOfString: [self thousandSeparator] - withString: @"" - options: 0 - range: NSMakeRange(0, [string length])]; + [(NSMutableString*)string replaceOccurrencesOfString: + [self thousandSeparator] + withString: @"" + options: 0 + range: NSMakeRange(0, [string length])]; } } @@ -223,6 +231,7 @@ _allowsFloats = YES; _decimalSeparator = '.'; _thousandSeparator = ','; + _hasThousandSeparators = YES; o = [[NSAttributedString alloc] initWithString: @""]; [self setAttributedStringForNil: o]; RELEASE(o); @@ -239,19 +248,23 @@ { if ([decoder containsValueForKey: @"NS.allowsfloats"]) { - [self setAllowsFloats: [decoder decodeBoolForKey: @"NS.allowsfloats"]]; + [self setAllowsFloats: + [decoder decodeBoolForKey: @"NS.allowsfloats"]]; } if ([decoder containsValueForKey: @"NS.decimal"]) { - [self setDecimalSeparator: [decoder decodeObjectForKey: @"NS.decimal"]]; + [self setDecimalSeparator: + [decoder decodeObjectForKey: @"NS.decimal"]]; } if ([decoder containsValueForKey: @"NS.hasthousands"]) { - [self setHasThousandSeparators: [decoder decodeBoolForKey: @"NS.hasthousands"]]; + [self setHasThousandSeparators: + [decoder decodeBoolForKey: @"NS.hasthousands"]]; } if ([decoder containsValueForKey: @"NS.localized"]) { - [self setLocalizesFormat: [decoder decodeBoolForKey: @"NS.localized"]]; + [self setLocalizesFormat: + [decoder decodeBoolForKey: @"NS.localized"]]; } if ([decoder containsValueForKey: @"NS.max"]) { @@ -263,44 +276,54 @@ } if ([decoder containsValueForKey: @"NS.nan"]) { - [self setAttributedStringForNotANumber: [decoder decodeObjectForKey: @"NS.nan"]]; + [self setAttributedStringForNotANumber: + [decoder decodeObjectForKey: @"NS.nan"]]; } if ([decoder containsValueForKey: @"NS.negativeattrs"]) { - [self setTextAttributesForNegativeValues: [decoder decodeObjectForKey: @"NS.negativeattrs"]]; + [self setTextAttributesForNegativeValues: + [decoder decodeObjectForKey: @"NS.negativeattrs"]]; } if ([decoder containsValueForKey: @"NS.negativeformat"]) { - [self setNegativeFormat: [decoder decodeObjectForKey: @"NS.negativeformat"]]; + [self setNegativeFormat: + [decoder decodeObjectForKey: @"NS.negativeformat"]]; } if ([decoder containsValueForKey: @"NS.nil"]) { - [self setAttributedStringForNil: [decoder decodeObjectForKey: @"NS.nil"]]; + [self setAttributedStringForNil: + [decoder decodeObjectForKey: @"NS.nil"]]; } if ([decoder containsValueForKey: @"NS.positiveattrs"]) { - [self setTextAttributesForPositiveValues: [decoder decodeObjectForKey: @"NS.positiveattrs"]]; + [self setTextAttributesForPositiveValues: + [decoder decodeObjectForKey: @"NS.positiveattrs"]]; } if ([decoder containsValueForKey: @"NS.positiveformat"]) { - [self setPositiveFormat: [decoder decodeObjectForKey: @"NS.positiveformat"]]; + [self setPositiveFormat: + [decoder decodeObjectForKey: @"NS.positiveformat"]]; } if ([decoder containsValueForKey: @"NS.rounding"]) { - [self setRoundingBehavior: [decoder decodeObjectForKey: @"NS.rounding"]]; + [self setRoundingBehavior: + [decoder decodeObjectForKey: @"NS.rounding"]]; } if ([decoder containsValueForKey: @"NS.thousand"]) { - [self setThousandSeparator: [decoder decodeObjectForKey: @"NS.thousand"]]; + [self setThousandSeparator: + [decoder decodeObjectForKey: @"NS.thousand"]]; } if ([decoder containsValueForKey: @"NS.zero"]) { - [self setAttributedStringForZero: [decoder decodeObjectForKey: @"NS.zero"]]; + [self setAttributedStringForZero: + [decoder decodeObjectForKey: @"NS.zero"]]; } } else { - [decoder decodeValueOfObjCType: @encode(BOOL) at: &_hasThousandSeparators]; + [decoder decodeValueOfObjCType: @encode(BOOL) + at: &_hasThousandSeparators]; [decoder decodeValueOfObjCType: @encode(BOOL) at: &_allowsFloats]; [decoder decodeValueOfObjCType: @encode(BOOL) at: &_localizesFormat]; [decoder decodeValueOfObjCType: @encode(unichar) at: &_thousandSeparator]; @@ -312,7 +335,8 @@ [decoder decodeValueOfObjCType: @encode(id) at: &_attributedStringForNil]; [decoder decodeValueOfObjCType: @encode(id) at: &_attributedStringForNotANumber]; - [decoder decodeValueOfObjCType: @encode(id) at: &_attributedStringForZero]; + [decoder decodeValueOfObjCType: @encode(id) + at: &_attributedStringForZero]; [decoder decodeValueOfObjCType: @encode(id) at: &_negativeFormat]; [decoder decodeValueOfObjCType: @encode(id) at: &_positiveFormat]; [decoder decodeValueOfObjCType: @encode(id) @@ -485,27 +509,233 @@ - (NSString*) stringForObjectValue: (id)anObject { - NSMutableDictionary *locale; + NSMutableDictionary *locale; + NSCharacterSet *formattingCharacters; + NSCharacterSet *placeHolders; + NSString *prefix; + NSString *suffix; + NSString *wholeString; + NSString *fracPad; + NSString *fracPartString; + NSMutableString *intPartString; + NSMutableString *formattedNumber; + NSMutableString *intPad; + NSRange prefixRange; + NSRange decimalPlaceRange; + NSRange suffixRange; + NSRange intPartRange; + NSDecimal representativeDecimal; + NSDecimal roundedDecimal; + NSDecimalNumber *roundedNumber; + NSDecimalNumber *intPart; + NSDecimalNumber *fracPart; + int decimalPlaces = 0; + BOOL displayThousandsSeparators = NO; + BOOL displayFractionalPart = NO; + BOOL negativeNumber = NO; + NSString *useFormat; + + formattingCharacters = [NSCharacterSet + characterSetWithCharactersInString: @"0123456789#.,_"]; + placeHolders = [NSCharacterSet + characterSetWithCharactersInString: @"0123456789#_"]; if (nil == anObject) return [[self attributedStringForNil] string]; + if (![anObject isKindOfClass: [NSNumber class]]) + return [[self attributedStringForNotANumber] string]; + if ([anObject isEqual: [NSDecimalNumber notANumber]]) + return [[self attributedStringForNotANumber] string]; + if ([anObject isEqual: [NSDecimalNumber zero]]) + return [[self attributedStringForZero] string]; + + useFormat = _positiveFormat; + if ([(NSNumber*)anObject compare: [NSDecimalNumber zero]] + == NSOrderedAscending) + { + useFormat = _negativeFormat; + negativeNumber = YES; + } - /* FIXME: This is just a quick hack implementation. */ - NSLog(@"NSNumberFormatter-stringForObjectValue:... not fully implemented"); + // if no format specified, use the same default that Cocoa does + if (nil == useFormat) + { + useFormat = negativeNumber ? @"-#,###.##" : @"#,###.##"; + } + + prefixRange = [useFormat rangeOfCharacterFromSet: formattingCharacters]; + if (NSNotFound != prefixRange.location) + { + prefix = [useFormat substringToIndex: prefixRange.location]; + } + else + { + prefix = @""; + } locale = [NSMutableDictionary dictionaryWithCapacity: 3]; - if ([self hasThousandSeparators]) + [locale setObject: @"" forKey: NSThousandsSeparator]; + [locale setObject: @"" forKey: NSDecimalSeparator]; + + //should also set NSDecimalDigits? + + if ([self hasThousandSeparators] + && (0 != [useFormat rangeOfString:@","].length)) { - [locale setObject: [self thousandSeparator] forKey: NSThousandsSeparator]; + displayThousandsSeparators = YES; } - if ([self allowsFloats]) + if ([self allowsFloats] + && (NSNotFound != [useFormat rangeOfString:@"." ].location)) { - [locale setObject: [self decimalSeparator] forKey: NSDecimalSeparator]; - // Should also set: NSDecimalDigits + decimalPlaceRange = [useFormat rangeOfString: @"." + options: NSBackwardsSearch]; + if (NSMaxRange(decimalPlaceRange) == [useFormat length]) + { + decimalPlaces = 0; + } + else + { + while ([placeHolders characterIsMember: + [useFormat characterAtIndex: NSMaxRange(decimalPlaceRange)]]) + { + decimalPlaceRange.length++; + if (NSMaxRange(decimalPlaceRange) == [useFormat length]) + break; + } + decimalPlaces=decimalPlaceRange.length -= 1; + decimalPlaceRange.location += 1; + fracPad = [useFormat substringWithRange:decimalPlaceRange]; + } + if (0 != decimalPlaces) + displayFractionalPart = YES; } - return [anObject descriptionWithLocale: locale]; + representativeDecimal = [anObject decimalValue]; + NSDecimalRound(&roundedDecimal, &representativeDecimal, decimalPlaces, + NSRoundPlain); + roundedNumber = [NSDecimalNumber decimalNumberWithDecimal: roundedDecimal]; + + /* Arguably this fiddling could be done by GSDecimalString() but I + * thought better to leave that behaviour as it is and provide the + * desired prettification here + */ + if (negativeNumber) + roundedNumber = [roundedNumber decimalNumberByMultiplyingBy: + (NSDecimalNumber*)[NSDecimalNumber numberWithInt: -1]]; + intPart = (NSDecimalNumber*) + [NSDecimalNumber numberWithInt: [roundedNumber intValue]]; + fracPart = [roundedNumber decimalNumberBySubtracting: intPart]; + intPartString + = AUTORELEASE([[intPart descriptionWithLocale: locale] mutableCopy]); + + //sort out the padding for the integer part + intPartRange = [useFormat rangeOfCharacterFromSet: placeHolders]; + if (NSMaxRange(intPartRange) < ([useFormat length] - 1)) + { + while (([placeHolders characterIsMember: + [useFormat characterAtIndex: NSMaxRange(intPartRange)]] + || [[useFormat substringFromRange: + NSMakeRange(NSMaxRange(intPartRange), 1)] isEqual: @","]) + && NSMaxRange(intPartRange) < [useFormat length] - 1) + { + intPartRange.length++; + } + } + intPad = [[useFormat substringWithRange: intPartRange] mutableCopy]; + [intPad replaceOccurrencesOfString: @"," + withString: @"" + options: 0 + range: NSMakeRange(0, [intPad length])]; + [intPad replaceOccurrencesOfString: @"#" + withString: @"" + options: NSAnchoredSearch + range: NSMakeRange(0, [intPad length])]; + if ([intPad length] > [intPartString length]) + { + NSRange ipRange; + + ipRange = NSMakeRange(0, [intPad length] - [intPartString length] + 1); + [intPartString insertString: + [intPad substringWithRange: ipRange] atIndex: 0]; + [intPartString replaceOccurrencesOfString: @"_" + withString: @" " + options: 0 + range: NSMakeRange(0, [intPartString length])]; + [intPartString replaceOccurrencesOfString: @"#" + withString: @"0" + options: 0 + range: NSMakeRange(0, [intPartString length])]; + } + // fix the thousands separators up + if (displayThousandsSeparators && [intPartString length] > 3) + { + int index = [intPartString length]; + + while (0 < (index -= 3)) + { + [intPartString insertString: [self thousandSeparator] atIndex: index]; + } + } + + formattedNumber = [intPartString mutableCopy]; + + //fix up the fractional part + if (displayFractionalPart) + { + if (0 != decimalPlaces) + { + NSMutableString *ms; + + fracPart = [fracPart decimalNumberByMultiplyingByPowerOf10: + decimalPlaces]; + ms = [[fracPart descriptionWithLocale: locale] mutableCopy]; + [ms replaceOccurrencesOfString: @"0" + withString: @"" + options: (NSBackwardsSearch | NSAnchoredSearch) + range: NSMakeRange(0, [ms length])]; + if ([fracPad length] > [ms length]) + { + NSRange fpRange; + + fpRange = NSMakeRange([ms length], + ([fracPad length] - [ms length])); + [ms appendString: + [fracPad substringWithRange: fpRange]]; + [ms replaceOccurrencesOfString: @"#" + withString: @"" + options: (NSBackwardsSearch | NSAnchoredSearch) + range: NSMakeRange(0, [ms length])]; + [ms replaceOccurrencesOfString: @"#" + withString: @"0" + options: 0 + range: NSMakeRange(0, [ms length])]; + [ms replaceOccurrencesOfString: @"_" + withString: @" " + options: 0 + range: NSMakeRange(0, [ms length])]; + } + fracPartString = AUTORELEASE(ms); + } + else + { + fracPartString = @"0"; + } + [formattedNumber appendString: [self decimalSeparator]]; + [formattedNumber appendString: fracPartString]; + } + /*FIXME - the suffix doesn't behave the same as on Mac OS X. + * Our suffix is everything which follows the final formatting + * character. Cocoa's suffix is everything which isn't a + * formatting character nor in the prefix + */ + suffixRange = [useFormat rangeOfCharacterFromSet: formattingCharacters + options: NSBackwardsSearch]; + suffix = [useFormat substringFromIndex: NSMaxRange(suffixRange)]; + wholeString = [[prefix stringByAppendingString: formattedNumber] + stringByAppendingString: suffix]; + [formattedNumber release]; + return wholeString; } - (NSDictionary*) textAttributesForNegativeValues diff --git a/Source/NSObjCRuntime.m b/Source/NSObjCRuntime.m index 18457156d..420398935 100644 --- a/Source/NSObjCRuntime.m +++ b/Source/NSObjCRuntime.m @@ -18,7 +18,8 @@ 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., 51 Franklin Street, Fifth Floor, Boston, MA 02111 USA. + Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02111 USA. NSObjCRuntime class reference $Date$ $Revision$ @@ -40,7 +41,7 @@ NSString * NSStringFromSelector(SEL aSelector) { if (aSelector != (SEL)0) - return [NSString stringWithCString: GSNameFromSelector(aSelector)]; + return [NSString stringWithUTF8String: GSNameFromSelector(aSelector)]; return nil; } @@ -92,7 +93,7 @@ NSString * NSStringFromClass(Class aClass) { if (aClass != (Class)0) - return [NSString stringWithCString: (char*)GSNameFromClass(aClass)]; + return [NSString stringWithUTF8String: (char*)GSNameFromClass(aClass)]; return nil; } diff --git a/Source/NSObject.m b/Source/NSObject.m index cd3ab62b1..ffdd3c9a1 100644 --- a/Source/NSObject.m +++ b/Source/NSObject.m @@ -25,6 +25,13 @@ $Date$ $Revision$ */ +/* On some versions of mingw we need to work around bad function declarations + * by defining them away and doing the declarations ourself later. + */ +#define InterlockedIncrement BadInterlockedIncrement +#define InterlockedDecrement BadInterlockedDecrement + + #include "config.h" #include "GNUstepBase/preface.h" #include @@ -65,6 +72,20 @@ extern BOOL __objc_responds_to(id, SEL); #endif +/* When this is `YES', every call to release/autorelease, checks to + make sure isn't being set up to release itself too many times. + This does not need mutex protection. */ +static BOOL double_release_check_enabled = NO; + +/* The Class responsible for handling autorelease's. This does not + need mutex protection, since it is simply a pointer that gets read + and set. */ +static id autorelease_class = nil; +static SEL autorelease_sel; +static IMP autorelease_imp; + + + #if GS_WITH_GC #include @@ -88,13 +109,12 @@ static Class NSConstantStringClass; @end /* - * allocationLock is needed when running multi-threaded for retain/release - * to work reliably. - * We also use it for protecting the map table of zombie information. + * allocationLock is needed when running multi-threaded for + * protecting the map table of zombie information and for retain + * count protection (when using a map table ... REFCNT_LOCAL is NO) */ static objc_mutex_t allocationLock = NULL; - BOOL NSZombieEnabled = NO; BOOL NSDeallocateZombies = NO; @@ -147,7 +167,7 @@ static void GSLogZombie(id o, SEL sel) NSLog(@"Deallocated %@ (0x%x) sent %@", NSStringFromClass(c), o, NSStringFromSelector(sel)); } - if (GSEnvironmentFlag("CRASH_ON_ZOMBIE", NO) == YES) + if (GSPrivateEnvironmentFlag("CRASH_ON_ZOMBIE", NO) == YES) { abort(); } @@ -173,6 +193,105 @@ static void GSLogZombie(id o, SEL sel) #define CACHE_ZONE 1 #endif + +/* Now, if we are on a platform where we know how to do atomic + * read, increment, and decrement, then we define the GSATOMICREAD + * macro and macros or functions to increment/decrement. + * The presence of the GSATOMICREAD macro is used later to determine + * whether to attempt atomic operations or to use locking for the + * retain/release mechanism. + * The GSAtomicIncrement() and GSAtomicDecrement() functions take a + * pointer to a 32bit integer as an argument, increment/decrement the + * value pointed to, and return the result. + */ +#ifdef GSATOMICREAD +#undef GSATOMICREAD +#endif + +#if defined(REFCNT_LOCAL) + +#if defined(__MINGW32__) + +#undef InterlockedIncrement +#undef InterlockedDecrement +LONG WINAPI InterlockedIncrement(LONG volatile *); +LONG WINAPI InterlockedDecrement(LONG volatile *); + +/* Set up atomic read, increment and decrement for mswindows + */ + +typedef int32_t volatile *gsatomic_t; + +#define GSATOMICREAD(X) (*(X)) + +#define GSAtomicIncrement(X) InterlockedIncrement((LONG volatile*)X) +#define GSAtomicDecrement(X) InterlockedDecrement((LONG volatile*)X) + +#endif + + +#if defined(__linux__) && (defined(__i386__) || defined(__x86_64__)) +/* Set up atomic read, increment and decrement for intel style linux + */ + +typedef int32_t volatile *gsatomic_t; + +#define GSATOMICREAD(X) (*(X)) + +static __inline__ int +GSAtomicIncrement(gsatomic_t X) +{ + int i = 1; + __asm__ __volatile__( + "lock ; xaddl %0, %1;" + :"=r"(i) + :"m"(*X), "0"(i)); + return i + 1; +} + +static __inline__ int +GSAtomicDecrement(gsatomic_t X) +{ + int i = -1; + __asm__ __volatile__( + "lock ; xaddl %0, %1;" + :"=r"(i) + :"m"(*X), "0"(i)); + return i - 1; +} + +#endif +#endif + +#if defined(REFCNT_LOCAL) && !defined(GSATOMICREAD) + +/* + * Having just one allocationLock for all leads to lock contention + * if there are lots of threads doing lots of retain/release calls. + * To alleviate this, if using REFCNT_LOCAL, instead of a single + * allocationLock for all objects, we divide the object space into + * chunks, each with its own lock. The chunk is selected by shifting + * off the low-order ALIGNBITS of the object's pointer (these bits + * are presumably always zero) and take + * the low-order LOCKBITS of the result to index into a table of locks. + */ + +#define LOCKBITS 5 +#define LOCKCOUNT (1<> ALIGNBITS) & LOCKMASK); + return allocationLocks[i]; +} + +#endif + + #ifdef ALIGN #undef ALIGN #endif @@ -242,27 +361,59 @@ static GSIMapTable_t retain_counts = {0}; * (and hence whether the extra reference count was decremented).
* This function is used by the [NSObject-release] method. */ -inline BOOL +BOOL NSDecrementExtraRefCountWasZero(id anObject) { -#if GS_WITH_GC - return NO; -#else /* GS_WITH_GC */ +#if !GS_WITH_GC + if (double_release_check_enabled) + { + unsigned release_count; + unsigned retain_count = [anObject retainCount]; + release_count = [autorelease_class autoreleaseCountForObject: anObject]; + if (release_count >= retain_count) + [NSException raise: NSGenericException + format: @"Release would release object too many times."]; + } #if defined(REFCNT_LOCAL) if (allocationLock != 0) { - objc_mutex_lock(allocationLock); +#if defined(GSATOMICREAD) + int result; + + result = GSAtomicDecrement((gsatomic_t)&(((obj)anObject)[-1].retained)); + if (result < 0) + { + if (result != -1) + { + [NSException raise: NSInternalInconsistencyException + format: @"NSDecrementExtraRefCount() decremented too far"]; + } + /* The counter has become negative so it must have been zero. + * We reset it and return YES ... in a correctly operating + * process we know we can safely reset back to zero without + * worrying about atomicity, since there can be no other + * thread accessing the object (or its reference count would + * have been greater than zero) + */ + (((obj)anObject)[-1].retained) = 0; + return YES; + } +#else /* GSATOMICREAD */ + objc_mutex_t theLock = GSAllocationLockForObject(anObject); + + objc_mutex_lock(theLock); if (((obj)anObject)[-1].retained == 0) { - objc_mutex_unlock(allocationLock); + objc_mutex_unlock(theLock); return YES; } else { ((obj)anObject)[-1].retained--; - objc_mutex_unlock(allocationLock); + objc_mutex_unlock(theLock); return NO; } +#endif /* GSATOMICREAD */ } else { @@ -317,9 +468,9 @@ NSDecrementExtraRefCountWasZero(id anObject) --(node->value.uint); } } +#endif +#endif return NO; -#endif -#endif } /** @@ -341,7 +492,9 @@ NSExtraRefCount(id anObject) if (allocationLock != 0) { - objc_mutex_lock(allocationLock); + objc_mutex_t theLock = GSAllocationLockForObject(anObject); + + objc_mutex_lock(theLock); node = GSIMapNodeForKey(&retain_counts, (GSIMapKey)anObject); if (node == 0) { @@ -351,7 +504,7 @@ NSExtraRefCount(id anObject) { ret = node->value.uint; } - objc_mutex_unlock(allocationLock); + objc_mutex_unlock(theLock); } else { @@ -385,15 +538,30 @@ NSIncrementExtraRefCount(id anObject) #if defined(REFCNT_LOCAL) if (allocationLock != 0) { - objc_mutex_lock(allocationLock); +#if defined(GSATOMICREAD) + /* I've seen comments saying that some platforms only support up to + * 24 bits in atomic locking, so raise an exception if we try to + * go beyond 0xfffffe. + */ + if (GSAtomicIncrement((gsatomic_t)&(((obj)anObject)[-1].retained)) + > 0xfffffe) + { + [NSException raise: NSInternalInconsistencyException + format: @"NSIncrementExtraRefCount() asked to increment too far"]; + } +#else /* GSATOMICREAD */ + objc_mutex_t theLock = GSAllocationLockForObject(anObject); + + objc_mutex_lock(theLock); if (((obj)anObject)[-1].retained == UINT_MAX - 1) { - objc_mutex_unlock (allocationLock); + objc_mutex_unlock (theLock); [NSException raise: NSInternalInconsistencyException format: @"NSIncrementExtraRefCount() asked to increment too far"]; } ((obj)anObject)[-1].retained++; - objc_mutex_unlock (allocationLock); + objc_mutex_unlock (theLock); +#endif /* GSATOMICREAD */ } else { @@ -404,8 +572,7 @@ NSIncrementExtraRefCount(id anObject) } ((obj)anObject)[-1].retained++; } - return; -#else +#else /* REFCNT_LOCAL */ GSIMapNode node; if (allocationLock != 0) @@ -447,9 +614,8 @@ NSIncrementExtraRefCount(id anObject) GSIMapAddPair(&retain_counts, (GSIMapKey)anObject, (GSIMapVal)1); } } - return; -#endif -#endif +#endif /* REFCNT_LOCAL */ +#endif /* GS_WITH_GC */ } @@ -696,20 +862,6 @@ NSShouldRetainWithZone (NSObject *anObject, NSZone *requestedZone) -/* The Class responsible for handling autorelease's. This does not - need mutex protection, since it is simply a pointer that gets read - and set. */ -static id autorelease_class = nil; -static SEL autorelease_sel; -static IMP autorelease_imp; - -/* When this is `YES', every call to release/autorelease, checks to - make sure isn't being set up to release itself too many times. - This does not need mutex protection. */ -static BOOL double_release_check_enabled = NO; - - - struct objc_method_description_list { int count; struct objc_method_description list[1]; @@ -859,6 +1011,14 @@ GSDescriptionForClassMethod(pcl self, SEL aSel) { if (allocationLock == 0) { +#if defined(REFCNT_LOCAL) && !defined(GSATOMICREAD) + unsigned i; + + for (i = 0; i < LOCKCOUNT; i++) + { + allocationLocks[i] = objc_mutex_allocate(); + } +#endif allocationLock = objc_mutex_allocate(); } } @@ -884,8 +1044,6 @@ GSDescriptionForClassMethod(pcl self, SEL aSel) { if (self == [NSObject class]) { - extern void GSBuildStrings(void); // See externs.m - #ifdef __MINGW32__ // See libgnustep-base-entry.m extern void gnustep_base_socket_init(void); @@ -960,8 +1118,8 @@ GSDescriptionForClassMethod(pcl self, SEL aSel) zombieMap = NSCreateMapTable(NSNonOwnedPointerMapKeyCallBacks, NSNonOwnedPointerMapValueCallBacks, 0); zombieClass = [NSZombie class]; - NSZombieEnabled = GSEnvironmentFlag("NSZombieEnabled", NO); - NSDeallocateZombies = GSEnvironmentFlag("NSDeallocateZombies", NO); + NSZombieEnabled = GSPrivateEnvironmentFlag("NSZombieEnabled", NO); + NSDeallocateZombies = GSPrivateEnvironmentFlag("NSDeallocateZombies", NO); autorelease_class = [NSAutoreleasePool class]; autorelease_sel = @selector(addObject:); @@ -973,7 +1131,7 @@ GSDescriptionForClassMethod(pcl self, SEL aSel) #endif #endif NSConstantStringClass = [NSString constantStringClass]; - GSBuildStrings(); + GSPrivateBuildStrings(); [[NSNotificationCenter defaultCenter] addObserver: self selector: @selector(_becomeMultiThreaded:) @@ -1287,7 +1445,7 @@ GSDescriptionForClassMethod(pcl self, SEL aSel) { if (aSelector == 0) { - if (GSUserDefaultsFlag(GSMacOSXCompatible)) + if (GSPrivateDefaultsFlag(GSMacOSXCompatible)) { [NSException raise: NSInvalidArgumentException format: @"%@ null selector given", @@ -1479,8 +1637,8 @@ GSDescriptionForClassMethod(pcl self, SEL aSel) */ - (NSString*) description { - return [NSString stringWithFormat: @"<%s: %lx>", - GSClassNameFromObject(self), (unsigned long)self]; + return [NSString stringWithFormat: @"<%s: %p>", + GSClassNameFromObject(self), self]; } /** @@ -1612,7 +1770,7 @@ GSDescriptionForClassMethod(pcl self, SEL aSel) * sent a -release message when the pool is destroyed.
* Returns the receiver.
* In GNUstep, the [NSObject+enableDoubleReleaseCheck:] method may be used - * to turn on checking for ratain/release errors in this method. + * to turn on checking for retain/release errors in this method. */ - (id) autorelease { @@ -1829,16 +1987,6 @@ GSDescriptionForClassMethod(pcl self, SEL aSel) - (oneway void) release { #if GS_WITH_GC == 0 - if (double_release_check_enabled) - { - unsigned release_count; - unsigned retain_count = [self retainCount]; - release_count = [autorelease_class autoreleaseCountForObject:self]; - if (release_count >= retain_count) - [NSException raise: NSGenericException - format: @"Release would release object too many times."]; - } - if (NSDecrementExtraRefCountWasZero(self)) { [self dealloc]; @@ -1870,7 +2018,7 @@ GSDescriptionForClassMethod(pcl self, SEL aSel) { if (aSelector == 0) { - if (GSUserDefaultsFlag(GSMacOSXCompatible)) + if (GSPrivateDefaultsFlag(GSMacOSXCompatible)) { [NSException raise: NSInvalidArgumentException format: @"%@ null selector given", @@ -2376,8 +2524,8 @@ GSDescriptionForClassMethod(pcl self, SEL aSel) } - (NSString*) description { - return [NSString stringWithFormat: @"<%s: %lx>", - GSClassNameFromObject(self), (unsigned long)self]; + return [NSString stringWithFormat: @"<%s: %p>", + GSClassNameFromObject(self), self]; } - (BOOL) isProxy { diff --git a/Source/NSPathUtilities.m b/Source/NSPathUtilities.m index a796fc5a4..5f1a417fe 100644 --- a/Source/NSPathUtilities.m +++ b/Source/NSPathUtilities.m @@ -111,14 +111,17 @@ static NSString *library_combo = #else nil; #endif -static NSString *gnustep_flattened = -#ifdef GNUSTEP_FLATTENED - @GNUSTEP_FLATTENED; +static NSString *gnustep_is_flattened = +#ifdef GNUSTEP_IS_FLATTENED + @GNUSTEP_IS_FLATTENED; #else nil; #endif #if defined(__MINGW32__) + +#include + /* * FIXME ... should check access properly if the file is on an NTFS volume. */ @@ -135,31 +138,84 @@ static NSString *gnustep_flattened = static NSString *gnustepConfigPath = nil; -/* We read these four paths only once */ -static NSString *gnustepUserRoot = nil; /* GNUSTEP_USER_ROOT path */ -static NSString *gnustepLocalRoot = nil; /* GNUSTEP_LOCAL_ROOT path */ -static NSString *gnustepNetworkRoot = nil; /* GNUSTEP_NETWORK_ROOT path */ -static NSString *gnustepSystemRoot = nil; /* GNUSTEP_SYSTEM_ROOT path */ - static NSString *gnustepUserDir = nil; static NSString *gnustepUserHome = nil; static NSString *gnustepUserDefaultsDir = nil; -static NSString *theUserName = nil; /* The user's login name */ +static NSString *theUserName = nil; /* The user's login name */ +static NSString *theFullUserName = nil; /* The user's full login name */ static NSString *tempDir = nil; /* user's temporary directory */ -static NSString *osSysApps = nil; -static NSString *osSysLibs = nil; -static NSString *osSysAdmin = nil; +/* The following list entirely describe our filesystem configuration. */ +static NSString *gnustepMakefiles = nil; -static NSString *platformResources = nil; -static NSString *platformApps = nil; -static NSString *platformLibs = nil; -static NSString *platformAdmin = nil; +static NSString *gnustepSystemUsersDir = nil; +static NSString *gnustepNetworkUsersDir = nil; +static NSString *gnustepLocalUsersDir = nil; -static NSString *localResources = nil; -static NSString *localApps = nil; -static NSString *localLibs = nil; +static NSString *gnustepSystemApps = nil; +static NSString *gnustepSystemAdminApps = nil; +static NSString *gnustepSystemWebApps = nil; +static NSString *gnustepSystemTools = nil; +static NSString *gnustepSystemAdminTools = nil; +static NSString *gnustepSystemLibrary = nil; +static NSString *gnustepSystemLibraries = nil; +static NSString *gnustepSystemHeaders = nil; +static NSString *gnustepSystemDocumentation = nil; +static NSString *gnustepSystemDocumentationInfo = nil; +static NSString *gnustepSystemDocumentationMan = nil; + +static NSString *gnustepNetworkApps = nil; +static NSString *gnustepNetworkAdminApps = nil; +static NSString *gnustepNetworkWebApps = nil; +static NSString *gnustepNetworkTools = nil; +static NSString *gnustepNetworkAdminTools = nil; +static NSString *gnustepNetworkLibrary = nil; +static NSString *gnustepNetworkLibraries = nil; +static NSString *gnustepNetworkHeaders = nil; +static NSString *gnustepNetworkDocumentation = nil; +static NSString *gnustepNetworkDocumentationInfo = nil; +static NSString *gnustepNetworkDocumentationMan = nil; + +static NSString *gnustepLocalApps = nil; +static NSString *gnustepLocalAdminApps = nil; +static NSString *gnustepLocalWebApps = nil; +static NSString *gnustepLocalTools = nil; +static NSString *gnustepLocalAdminTools = nil; +static NSString *gnustepLocalLibrary = nil; +static NSString *gnustepLocalLibraries = nil; +static NSString *gnustepLocalHeaders = nil; +static NSString *gnustepLocalDocumentation = nil; +static NSString *gnustepLocalDocumentationInfo = nil; +static NSString *gnustepLocalDocumentationMan = nil; + +static NSString *gnustepUserApps = nil; +static NSString *gnustepUserAdminApps = nil; +static NSString *gnustepUserWebApps = nil; +static NSString *gnustepUserTools = nil; +static NSString *gnustepUserAdminTools = nil; +static NSString *gnustepUserLibrary = nil; +static NSString *gnustepUserLibraries = nil; +static NSString *gnustepUserHeaders = nil; +static NSString *gnustepUserDocumentation = nil; +static NSString *gnustepUserDocumentationInfo = nil; +static NSString *gnustepUserDocumentationMan = nil; + +/* These are the same as the corresponding User variables, but + * they hold the path before GNUSTEP_HOME is prepended. It's what + * we read from config files. + */ +static NSString *gnustepUserDirApps = nil; +static NSString *gnustepUserDirAdminApps = nil; +static NSString *gnustepUserDirWebApps = nil; +static NSString *gnustepUserDirTools = nil; +static NSString *gnustepUserDirAdminTools = nil; +static NSString *gnustepUserDirLibrary = nil; +static NSString *gnustepUserDirLibraries = nil; +static NSString *gnustepUserDirHeaders = nil; +static NSString *gnustepUserDirDocumentation = nil; +static NSString *gnustepUserDirDocumentationInfo = nil; +static NSString *gnustepUserDirDocumentationMan = nil; static BOOL ParseConfigurationFile(NSString *name, NSMutableDictionary *dict, NSString *userName); @@ -200,6 +256,15 @@ static void ShutdownPathUtilities(void); }\ }) +#define ASSIGN_DEFAULT_PATH(var, default) ({\ + if (var == nil)\ + {\ + var = default; \ + var = RETAIN(getPath(var)); \ + }\ + }) + + /* Get a full path string */ static inline NSString * getPath(NSString *path) @@ -258,25 +323,62 @@ static void ExtractValuesFromConfig(NSDictionary *config) /* * Move values out of the dictionary and into variables for rapid reference. */ - ASSIGN_PATH(gnustepSystemRoot, c, @"GNUSTEP_SYSTEM_ROOT"); - ASSIGN_PATH(gnustepNetworkRoot, c, @"GNUSTEP_NETWORK_ROOT"); - ASSIGN_PATH(gnustepLocalRoot, c, @"GNUSTEP_LOCAL_ROOT"); - ASSIGN_IF_SET(gnustepUserDir, c, @"GNUSTEP_USER_DIR"); ASSIGN_IF_SET(gnustepUserDefaultsDir, c, @"GNUSTEP_USER_DEFAULTS_DIR"); - ASSIGN_PATH(osSysApps, c, @"GNUSTEP_SYS_APPS"); - ASSIGN_PATH(osSysLibs, c, @"GNUSTEP_SYS_LIBS"); - ASSIGN_PATH(osSysAdmin, c, @"GNUSTEP_SYS_ADMIN"); + ASSIGN_PATH(gnustepMakefiles, c, @"GNUSTEP_MAKEFILES"); - ASSIGN_PATH(platformResources, c, @"GNUSTEP_PLATFORM_RESOURCES"); - ASSIGN_PATH(platformApps, c, @"GNUSTEP_PLATFORM_APPS"); - ASSIGN_PATH(platformLibs, c, @"GNUSTEP_PLATFORM_LIBS"); - ASSIGN_PATH(platformAdmin, c, @"GNUSTEP_PLATFORM_ADMIN"); + ASSIGN_PATH(gnustepSystemUsersDir, c, @"GNUSTEP_SYSTEM_USERS_DIR"); + ASSIGN_PATH(gnustepNetworkUsersDir, c, @"GNUSTEP_NETWORK_USERS_DIR"); + ASSIGN_PATH(gnustepLocalUsersDir, c, @"GNUSTEP_LOCAL_USERS_DIR"); - ASSIGN_PATH(localResources, c, @"GNUSTEP_PLATFORM_LOCAL_RESOURCES"); - ASSIGN_PATH(localApps, c, @"GNUSTEP_PLATFORM_LOCAL_APPS"); - ASSIGN_PATH(localLibs, c, @"GNUSTEP_PLATFORM_LOCAL_LIBS"); + ASSIGN_PATH(gnustepSystemApps, c, @"GNUSTEP_SYSTEM_APPS"); + ASSIGN_PATH(gnustepSystemAdminApps, c, @"GNUSTEP_SYSTEM_ADMIN_APPS"); + ASSIGN_PATH(gnustepSystemWebApps, c, @"GNUSTEP_SYSTEM_WEB_APPS"); + ASSIGN_PATH(gnustepSystemTools, c, @"GNUSTEP_SYSTEM_TOOLS"); + ASSIGN_PATH(gnustepSystemAdminTools, c, @"GNUSTEP_SYSTEM_ADMIN_TOOLS"); + ASSIGN_PATH(gnustepSystemLibrary, c, @"GNUSTEP_SYSTEM_LIBRARY"); + ASSIGN_PATH(gnustepSystemLibraries, c, @"GNUSTEP_SYSTEM_LIBRARIES"); + ASSIGN_PATH(gnustepSystemHeaders, c, @"GNUSTEP_SYSTEM_HEADERS"); + ASSIGN_PATH(gnustepSystemDocumentation, c, @"GNUSTEP_SYSTEM_DOC"); + ASSIGN_PATH(gnustepSystemDocumentationMan, c, @"GNUSTEP_SYSTEM_DOC_MAN"); + ASSIGN_PATH(gnustepSystemDocumentationInfo, c, @"GNUSTEP_SYSTEM_DOC_INFO"); + + ASSIGN_PATH(gnustepNetworkApps, c, @"GNUSTEP_NETWORK_APPS"); + ASSIGN_PATH(gnustepNetworkAdminApps, c, @"GNUSTEP_NETWORK_ADMIN_APPS"); + ASSIGN_PATH(gnustepNetworkWebApps, c, @"GNUSTEP_NETWORK_WEB_APPS"); + ASSIGN_PATH(gnustepNetworkTools, c, @"GNUSTEP_NETWORK_TOOLS"); + ASSIGN_PATH(gnustepNetworkAdminTools, c, @"GNUSTEP_NETWORK_ADMIN_TOOLS"); + ASSIGN_PATH(gnustepNetworkLibrary, c, @"GNUSTEP_NETWORK_LIBRARY"); + ASSIGN_PATH(gnustepNetworkLibraries, c, @"GNUSTEP_NETWORK_LIBRARIES"); + ASSIGN_PATH(gnustepNetworkHeaders, c, @"GNUSTEP_NETWORK_HEADERS"); + ASSIGN_PATH(gnustepNetworkDocumentation, c, @"GNUSTEP_NETWORK_DOC"); + ASSIGN_PATH(gnustepNetworkDocumentationMan, c, @"GNUSTEP_NETWORK_DOC_MAN"); + ASSIGN_PATH(gnustepNetworkDocumentationInfo, c, @"GNUSTEP_NETWORK_DOC_INFO"); + + ASSIGN_PATH(gnustepLocalApps, c, @"GNUSTEP_LOCAL_APPS"); + ASSIGN_PATH(gnustepLocalAdminApps, c, @"GNUSTEP_LOCAL_ADMIN_APPS"); + ASSIGN_PATH(gnustepLocalWebApps, c, @"GNUSTEP_LOCAL_WEB_APPS"); + ASSIGN_PATH(gnustepLocalTools, c, @"GNUSTEP_LOCAL_TOOLS"); + ASSIGN_PATH(gnustepLocalAdminTools, c, @"GNUSTEP_LOCAL_ADMIN_TOOLS"); + ASSIGN_PATH(gnustepLocalLibrary, c, @"GNUSTEP_LOCAL_LIBRARY"); + ASSIGN_PATH(gnustepLocalLibraries, c, @"GNUSTEP_LOCAL_LIBRARIES"); + ASSIGN_PATH(gnustepLocalHeaders, c, @"GNUSTEP_LOCAL_HEADERS"); + ASSIGN_PATH(gnustepLocalDocumentation, c, @"GNUSTEP_LOCAL_DOC"); + ASSIGN_PATH(gnustepLocalDocumentationMan, c, @"GNUSTEP_LOCAL_DOC_MAN"); + ASSIGN_PATH(gnustepLocalDocumentationInfo, c, @"GNUSTEP_LOCAL_DOC_INFO"); + + ASSIGN_IF_SET(gnustepUserDirApps, c, @"GNUSTEP_USER_DIR_APPS"); + ASSIGN_IF_SET(gnustepUserDirAdminApps, c, @"GNUSTEP_USER_DIR_ADMIN_APPS"); + ASSIGN_IF_SET(gnustepUserDirWebApps, c, @"GNUSTEP_USER_DIR_WEB_APPS"); + ASSIGN_IF_SET(gnustepUserDirTools, c, @"GNUSTEP_USER_DIR_TOOLS"); + ASSIGN_IF_SET(gnustepUserDirAdminTools, c, @"GNUSTEP_USER_DIR_ADMIN_TOOLS"); + ASSIGN_IF_SET(gnustepUserDirLibrary, c, @"GNUSTEP_USER_DIR_LIBRARY"); + ASSIGN_IF_SET(gnustepUserDirLibraries, c, @"GNUSTEP_USER_DIR_LIBRARIES"); + ASSIGN_IF_SET(gnustepUserDirHeaders, c, @"GNUSTEP_USER_DIR_HEADERS"); + ASSIGN_IF_SET(gnustepUserDirDocumentation, c, @"GNUSTEP_USER_DIR_DOC"); + ASSIGN_IF_SET(gnustepUserDirDocumentationMan, c, @"GNUSTEP_USER_DIR_DOC_MAN"); + ASSIGN_IF_SET(gnustepUserDirDocumentationInfo, c, @"GNUSTEP_USER_DIR_DOC_INFO"); /* * The GNUSTEP_EXTRA field may contain a list of extra keys which @@ -302,6 +404,12 @@ static void ExtractValuesFromConfig(NSDictionary *config) */ [c removeObjectForKey: @"GNUSTEP_USER_CONFIG_FILE"]; + /* FIXME ... for the time being we just ignore obsolete keys */ + [c removeObjectForKey: @"GNUSTEP_USER_ROOT"]; + [c removeObjectForKey: @"GNUSTEP_LOCAL_ROOT"]; + [c removeObjectForKey: @"GNUSTEP_SYSTEM_ROOT"]; + [c removeObjectForKey: @"GNUSTEP_NETWORK_ROOT"]; + if ([c count] > 0) { /* @@ -323,11 +431,81 @@ static void ExtractValuesFromConfig(NSDictionary *config) { ASSIGN(gnustepUserDefaultsDir, @GNUSTEP_TARGET_USER_DEFAULTS_DIR); } + if (gnustepUserDirApps == nil) + { + ASSIGN(gnustepUserDirApps, @GNUSTEP_TARGET_USER_DIR_APPS); + } + if (gnustepUserDirTools == nil) + { + ASSIGN(gnustepUserDirTools, @GNUSTEP_TARGET_USER_DIR_TOOLS); + } + if (gnustepUserDirLibrary == nil) + { + ASSIGN(gnustepUserDirLibrary, @GNUSTEP_TARGET_USER_DIR_LIBRARY); + } + if (gnustepUserDirLibraries == nil) + { + ASSIGN(gnustepUserDirLibraries, @GNUSTEP_TARGET_USER_DIR_LIBRARIES); + } + if (gnustepUserDirHeaders == nil) + { + ASSIGN(gnustepUserDirHeaders, @GNUSTEP_TARGET_USER_DIR_HEADERS); + } + if (gnustepUserDirDocumentation == nil) + { + ASSIGN(gnustepUserDirDocumentation, + @GNUSTEP_TARGET_USER_DIR_DOC); + } + if (gnustepUserDirDocumentationMan == nil) + { + ASSIGN(gnustepUserDirDocumentationMan, + @GNUSTEP_TARGET_USER_DIR_DOC_MAN); + } + if (gnustepUserDirDocumentationInfo == nil) + { + ASSIGN(gnustepUserDirDocumentationInfo, + @GNUSTEP_TARGET_USER_DIR_DOC_INFO); + } + /* - * Set the user root from the user home and the user dir + * Set the GNUSTEP_USER_xxx variables from the user home and the + * GNUSTEP_USER_DIR_xxx variables. */ - ASSIGN(gnustepUserRoot, - [gnustepUserHome stringByAppendingPathComponent: gnustepUserDir]); + ASSIGN(gnustepUserApps, + [gnustepUserHome stringByAppendingPathComponent: gnustepUserDirApps]); + + ASSIGN(gnustepUserAdminApps, + [gnustepUserHome stringByAppendingPathComponent: gnustepUserDirAdminApps]); + + ASSIGN(gnustepUserWebApps, + [gnustepUserHome stringByAppendingPathComponent: gnustepUserDirWebApps]); + + ASSIGN(gnustepUserTools, + [gnustepUserHome stringByAppendingPathComponent: gnustepUserDirTools]); + + ASSIGN(gnustepUserAdminTools, + [gnustepUserHome stringByAppendingPathComponent: gnustepUserDirAdminTools]); + + ASSIGN(gnustepUserLibrary, + [gnustepUserHome stringByAppendingPathComponent: gnustepUserDirLibrary]); + + ASSIGN(gnustepUserLibraries, + [gnustepUserHome stringByAppendingPathComponent: gnustepUserDirLibraries]); + + ASSIGN(gnustepUserHeaders, + [gnustepUserHome stringByAppendingPathComponent: gnustepUserDirHeaders]); + + ASSIGN(gnustepUserDocumentation, + [gnustepUserHome stringByAppendingPathComponent: + gnustepUserDocumentation]); + + ASSIGN(gnustepUserDocumentationMan, + [gnustepUserHome stringByAppendingPathComponent: + gnustepUserDocumentationMan]); + + ASSIGN(gnustepUserDocumentationInfo, + [gnustepUserHome stringByAppendingPathComponent: + gnustepUserDocumentationInfo]); /* * Try to ensure that essential user directories exist. @@ -344,16 +522,8 @@ static void ExtractValuesFromConfig(NSDictionary *config) attr = [NSDictionary dictionaryWithObject: [NSNumber numberWithInt: 0750] forKey: NSFilePosixPermissions]; - // make sure user root exists. - path = gnustepUserRoot; - if ([manager fileExistsAtPath: path isDirectory: &flag] == NO - || flag == NO) - { - [manager createDirectoryAtPath: path attributes: attr]; - } - - // make sure library directory exists (to store resources). - path = [path stringByAppendingPathComponent: @"Library"]; + // Make sure library directory exists (to store resources). + path = gnustepUserLibrary; if ([manager fileExistsAtPath: path isDirectory: &flag] == NO || flag == NO) { @@ -364,21 +534,47 @@ static void ExtractValuesFromConfig(NSDictionary *config) /* * Finally set default locations for the essential paths if required. */ - if (gnustepSystemRoot == nil) - { - gnustepSystemRoot = @GNUSTEP_TARGET_SYSTEM_ROOT; - gnustepSystemRoot = RETAIN(getPath(gnustepSystemRoot)); - } - if (gnustepNetworkRoot == nil) - { - gnustepNetworkRoot = @GNUSTEP_TARGET_NETWORK_ROOT; - gnustepNetworkRoot = RETAIN(getPath(gnustepNetworkRoot)); - } - if (gnustepLocalRoot == nil) - { - gnustepLocalRoot = @GNUSTEP_TARGET_LOCAL_ROOT; - gnustepLocalRoot = RETAIN(getPath(gnustepLocalRoot)); - } + ASSIGN_DEFAULT_PATH(gnustepSystemApps, @GNUSTEP_TARGET_SYSTEM_APPS); + ASSIGN_DEFAULT_PATH(gnustepSystemAdminApps, @GNUSTEP_TARGET_SYSTEM_ADMIN_APPS); + ASSIGN_DEFAULT_PATH(gnustepSystemWebApps, @GNUSTEP_TARGET_SYSTEM_WEB_APPS); + ASSIGN_DEFAULT_PATH(gnustepSystemTools, @GNUSTEP_TARGET_SYSTEM_TOOLS); + ASSIGN_DEFAULT_PATH(gnustepSystemAdminTools, @GNUSTEP_TARGET_SYSTEM_ADMIN_TOOLS); + ASSIGN_DEFAULT_PATH(gnustepSystemLibrary, @GNUSTEP_TARGET_SYSTEM_LIBRARY); + ASSIGN_DEFAULT_PATH(gnustepSystemLibraries, @GNUSTEP_TARGET_SYSTEM_LIBRARIES); + ASSIGN_DEFAULT_PATH(gnustepSystemHeaders, @GNUSTEP_TARGET_SYSTEM_HEADERS); + ASSIGN_DEFAULT_PATH(gnustepSystemDocumentation, @GNUSTEP_TARGET_SYSTEM_DOC); + ASSIGN_DEFAULT_PATH(gnustepSystemDocumentationMan, @GNUSTEP_TARGET_SYSTEM_DOC_MAN); + ASSIGN_DEFAULT_PATH(gnustepSystemDocumentationInfo, @GNUSTEP_TARGET_SYSTEM_DOC_INFO); + + ASSIGN_DEFAULT_PATH(gnustepNetworkApps, @GNUSTEP_TARGET_NETWORK_APPS); + ASSIGN_DEFAULT_PATH(gnustepNetworkAdminApps, @GNUSTEP_TARGET_NETWORK_ADMIN_APPS); + ASSIGN_DEFAULT_PATH(gnustepNetworkWebApps, @GNUSTEP_TARGET_NETWORK_WEB_APPS); + ASSIGN_DEFAULT_PATH(gnustepNetworkTools, @GNUSTEP_TARGET_NETWORK_TOOLS); + ASSIGN_DEFAULT_PATH(gnustepNetworkAdminTools, @GNUSTEP_TARGET_NETWORK_ADMIN_TOOLS); + ASSIGN_DEFAULT_PATH(gnustepNetworkLibrary, @GNUSTEP_TARGET_NETWORK_LIBRARY); + ASSIGN_DEFAULT_PATH(gnustepNetworkLibraries, @GNUSTEP_TARGET_NETWORK_LIBRARIES); + ASSIGN_DEFAULT_PATH(gnustepNetworkHeaders, @GNUSTEP_TARGET_NETWORK_HEADERS); + ASSIGN_DEFAULT_PATH(gnustepNetworkDocumentation, @GNUSTEP_TARGET_NETWORK_DOC); + ASSIGN_DEFAULT_PATH(gnustepNetworkDocumentationMan, @GNUSTEP_TARGET_NETWORK_DOC_MAN); + ASSIGN_DEFAULT_PATH(gnustepNetworkDocumentationInfo, @GNUSTEP_TARGET_NETWORK_DOC_INFO); + + ASSIGN_DEFAULT_PATH(gnustepLocalApps, @GNUSTEP_TARGET_LOCAL_APPS); + ASSIGN_DEFAULT_PATH(gnustepLocalAdminApps, @GNUSTEP_TARGET_LOCAL_ADMIN_APPS); + ASSIGN_DEFAULT_PATH(gnustepLocalWebApps, @GNUSTEP_TARGET_LOCAL_WEB_APPS); + ASSIGN_DEFAULT_PATH(gnustepLocalTools, @GNUSTEP_TARGET_LOCAL_TOOLS); + ASSIGN_DEFAULT_PATH(gnustepLocalAdminTools, @GNUSTEP_TARGET_LOCAL_ADMIN_TOOLS); + ASSIGN_DEFAULT_PATH(gnustepLocalLibrary, @GNUSTEP_TARGET_LOCAL_LIBRARY); + ASSIGN_DEFAULT_PATH(gnustepLocalLibraries, @GNUSTEP_TARGET_LOCAL_LIBRARIES); + ASSIGN_DEFAULT_PATH(gnustepLocalHeaders, @GNUSTEP_TARGET_LOCAL_HEADERS); + ASSIGN_DEFAULT_PATH(gnustepLocalDocumentation, @GNUSTEP_TARGET_LOCAL_DOC); + ASSIGN_DEFAULT_PATH(gnustepLocalDocumentationMan, @GNUSTEP_TARGET_LOCAL_DOC_MAN); + ASSIGN_DEFAULT_PATH(gnustepLocalDocumentationInfo, @GNUSTEP_TARGET_LOCAL_DOC_INFO); + + ASSIGN_DEFAULT_PATH(gnustepMakefiles, @GNUSTEP_TARGET_MAKEFILES); + + ASSIGN_DEFAULT_PATH(gnustepSystemUsersDir, @GNUSTEP_TARGET_SYSTEM_USERS_DIR); + ASSIGN_DEFAULT_PATH(gnustepNetworkUsersDir, @GNUSTEP_TARGET_NETWORK_USERS_DIR); + ASSIGN_DEFAULT_PATH(gnustepLocalUsersDir, @GNUSTEP_TARGET_LOCAL_USERS_DIR); } NSMutableDictionary* @@ -429,7 +625,7 @@ GNUstepConfig(NSDictionary *newConfig) if ([file hasPrefix: @"./"] == YES) { Class c = [NSProcessInfo class]; - NSString *path = objc_get_symbol_path (c, 0); + NSString *path = GSPrivateSymbolPath (c, 0); // Remove library name from path path = [path stringByDeletingLastPathComponent]; @@ -572,7 +768,7 @@ GNUstepUserConfig(NSMutableDictionary *config, NSString *userName) /* Initialise all things required by this module */ static void InitialisePathUtilities(void) { - if (gnustepSystemRoot != nil) + if (gnustepMakefiles != nil) { return; // Protect from multiple calls } @@ -606,26 +802,62 @@ static void InitialisePathUtilities(void) */ static void ShutdownPathUtilities(void) { - DESTROY(gnustepSystemRoot); - DESTROY(gnustepNetworkRoot); - DESTROY(gnustepLocalRoot); - DESTROY(gnustepUserRoot); - DESTROY(gnustepUserHome); DESTROY(gnustepUserDefaultsDir); - DESTROY(osSysApps); - DESTROY(osSysLibs); - DESTROY(osSysAdmin); + DESTROY(gnustepMakefiles); - DESTROY(platformResources); - DESTROY(platformApps); - DESTROY(platformLibs); - DESTROY(platformAdmin); + DESTROY(gnustepSystemUsersDir); + DESTROY(gnustepNetworkUsersDir); + DESTROY(gnustepLocalUsersDir); - DESTROY(localResources); - DESTROY(localApps); - DESTROY(localLibs); + DESTROY(gnustepSystemApps); + DESTROY(gnustepSystemAdminApps); + DESTROY(gnustepSystemWebApps); + DESTROY(gnustepSystemTools); + DESTROY(gnustepSystemAdminTools); + DESTROY(gnustepSystemLibrary); + DESTROY(gnustepSystemLibraries); + DESTROY(gnustepSystemHeaders); + DESTROY(gnustepSystemDocumentation); + DESTROY(gnustepSystemDocumentationMan); + DESTROY(gnustepSystemDocumentationInfo); + + DESTROY(gnustepNetworkApps); + DESTROY(gnustepNetworkAdminApps); + DESTROY(gnustepNetworkWebApps); + DESTROY(gnustepNetworkTools); + DESTROY(gnustepNetworkAdminTools); + DESTROY(gnustepNetworkLibrary); + DESTROY(gnustepNetworkLibraries); + DESTROY(gnustepNetworkHeaders); + DESTROY(gnustepNetworkDocumentation); + DESTROY(gnustepNetworkDocumentationMan); + DESTROY(gnustepNetworkDocumentationInfo); + + DESTROY(gnustepLocalApps); + DESTROY(gnustepLocalAdminApps); + DESTROY(gnustepLocalWebApps); + DESTROY(gnustepLocalTools); + DESTROY(gnustepLocalAdminTools); + DESTROY(gnustepLocalLibrary); + DESTROY(gnustepLocalLibraries); + DESTROY(gnustepLocalHeaders); + DESTROY(gnustepLocalDocumentation); + DESTROY(gnustepLocalDocumentationMan); + DESTROY(gnustepLocalDocumentationInfo); + + DESTROY(gnustepUserApps); + DESTROY(gnustepUserAdminApps); + DESTROY(gnustepUserWebApps); + DESTROY(gnustepUserTools); + DESTROY(gnustepUserAdminTools); + DESTROY(gnustepUserLibrary); + DESTROY(gnustepUserLibraries); + DESTROY(gnustepUserHeaders); + DESTROY(gnustepUserDocumentation); + DESTROY(gnustepUserDocumentationMan); + DESTROY(gnustepUserDocumentationInfo); DESTROY(tempDir); } @@ -969,6 +1201,7 @@ GSSetUserName(NSString *aName) * Reset things as new user */ ASSIGN(theUserName, aName); + DESTROY(theFullUserName); InitialisePathUtilities(); [NSUserDefaults resetStandardUserDefaults]; @@ -980,7 +1213,8 @@ GSSetUserName(NSString *aName) * Under unix-like systems, the name associated with the current * effective user ID is used.
* Under ms-windows, the 'LOGNAME' environment is used, or if that fails, the - * GetUserName() call is used to find the user name. + * GetUserName() call is used to find the user name.
+ * Raises an exception on failure. */ /* NOTE FOR DEVELOPERS. * If you change the behavior of this method you must also change @@ -1076,7 +1310,7 @@ NSHomeDirectoryForUser(NSString *loginName) pw = getpwnam ([loginName cString]); if (pw != 0 && pw->pw_dir != NULL) { - s = [NSString stringWithCString: pw->pw_dir]; + s = [NSString stringWithUTF8String: pw->pw_dir]; } [gnustep_global_lock unlock]; #else @@ -1122,34 +1356,41 @@ NSHomeDirectoryForUser(NSString *loginName) return s; } -/** - * Returns the full username of the current user. - * If unable to determine this, returns the standard user name. - */ NSString * NSFullUserName(void) { + if (theFullUserName == nil) + { + NSString *userName = NSUserName(); #if defined(__MINGW32__) - /* FIXME: Win32 way to get full user name via Net API */ - return NSUserName(); + struct _USER_INFO_2 *userInfo; + + if (NetUserGetInfo(NULL, (unichar*)[userName cStringUsingEncoding: + NSUnicodeStringEncoding], 2, (LPBYTE*)&userInfo) == 0) + { + userName = [NSString stringWithCharacters: userInfo->usri2_full_name + length: wcslen(userInfo->usri2_full_name)]; + } #else #ifdef HAVE_PWD_H - struct passwd *pw; + struct passwd *pw; - pw = getpwnam([NSUserName() cString]); - return [NSString stringWithCString: pw->pw_gecos]; + pw = getpwnam([NSUserName() cString]); + userName = [NSString stringWithUTF8String: pw->pw_gecos]; #else - NSLog(@"Warning: NSFullUserName not implemented\n"); - return NSUserName(); + NSLog(@"Warning: NSFullUserName not implemented\n"); + userName = NSUserName(); #endif /* HAVE_PWD_H */ #endif /* defined(__Win32__) else */ + ASSIGN(theFullUserName, userName); + } + return theFullUserName; } /** * Return the path of the defaults directory for userName.
- * This examines the .GNUsteprc file in the home directory of the - * user for the GNUSTEP_DEFAULTS_ROOT or the GNUSTEP_USER_ROOT - * directory definitions, over-riding those in GNUstep.conf. + * This examines the GNUSTEP_USER_CONFIG_FILE for the specified user, + * with settings in it over-riding those in the main GNUstep.conf. */ NSString * GSDefaultsRootForUser(NSString *userName) @@ -1190,11 +1431,6 @@ GSDefaultsRootForUser(NSString *userName) return home; } -/** - * Returns the standard paths in which applications are stored and - * should be searched for. Calls NSSearchPathForDirectoriesInDomains()
- * Refer to the GNUstep File System Hierarchy documentation for more info. - */ NSArray * NSStandardApplicationPaths(void) { @@ -1202,11 +1438,6 @@ NSStandardApplicationPaths(void) NSAllDomainsMask, YES); } -/** - * Returns the standard paths in which resources are stored and - * should be searched for. Calls NSSearchPathForDirectoriesInDomains()
- * Refer to the GNUstep File System Hierarchy documentation for more info. - */ NSArray * NSStandardLibraryPaths(void) { @@ -1214,13 +1445,6 @@ NSStandardLibraryPaths(void) NSAllDomainsMask, YES); } -/** - * Returns the name of a directory in which temporary files can be stored. - * Under GNUstep this is a location which is not readable by other users. - *
- * If a suitable directory can't be found or created, this function raises an - * NSGenericException. - */ NSString * NSTemporaryDirectory(void) { @@ -1278,10 +1502,8 @@ NSTemporaryDirectory(void) if ([manager fileExistsAtPath: tempDirName isDirectory: &flag] == NO || flag == NO) { - [NSException raise: NSGenericException - format: @"Temporary directory (%@) does not exist", - tempDirName]; - return nil; /* Not reached. */ + NSWarnFLog(@"Temporary directory (%@) does not exist", tempDirName); + return nil; } /* @@ -1320,10 +1542,7 @@ NSTemporaryDirectory(void) secure = [NSString stringWithFormat: @"GNUstepSecure%d", uid]; tempDirName = [baseTempDirName stringByAppendingPathComponent: secure]; - /* - NSLog(@"Temporary directory (%@) may be insecure ... attempting to " - @"add secure subdirectory", tempDirName); - */ + if ([manager fileExistsAtPath: tempDirName] == NO) { NSNumber *p = [NSNumber numberWithInt: 0700]; @@ -1333,11 +1552,9 @@ NSTemporaryDirectory(void) if ([manager createDirectoryAtPath: tempDirName attributes: attr] == NO) { - [NSException raise: NSGenericException - format: - @"Attempt to create a secure temporary directory (%@) failed.", - tempDirName]; - return nil; /* Not reached. */ + NSWarnFLog(@"Attempt to create a secure temporary" + @" directory (%@) failed.", tempDirName); + return nil; } } @@ -1350,36 +1567,21 @@ NSTemporaryDirectory(void) perm = perm & 0777; if ((perm != 0700 && perm != 0600) || owner != uid) { - [NSException raise: NSGenericException - format: - @"Attempt to create a secure temporary directory (%@) failed.", - tempDirName]; - return nil; /* Not reached. */ + NSWarnFLog(@"Attempt to create a secure temporary" + @" directory (%@) failed.", tempDirName); + return nil; } } #endif if ([manager isWritableFileAtPath: tempDirName] == NO) { - [NSException raise: NSGenericException - format: @"Temporary directory (%@) is not writable", - tempDirName]; - return nil; /* Not reached. */ + NSWarnFLog(@"Temporary directory (%@) is not writable", tempDirName); + return nil; } return tempDirName; } -/** - * Returns the location of the root directory of the file - * hierarchy. This lets you build paths in a system independent manner - * (for instance the root on unix is '/' but on windows it is 'C:\') - * by appending path components to the root.
- * Don't assume that /System, /Network etc exist in this path (generally - * they don't)! Use other path utility functions such as - * NSSearchPathForDirectoriesInDomains() to find standard locations - * for libraries, applications etc.
- * Refer to the GNUstep File System Hierarchy documentation for more info. - */ NSString * NSOpenStepRootDirectory(void) { @@ -1395,25 +1597,10 @@ NSOpenStepRootDirectory(void) return root; } -/** - * Returns an array of search paths to look at for resources.
- * The paths are returned in domain order: USER, LOCAL, NETWORK then SYSTEM. - */ NSArray * NSSearchPathForDirectoriesInDomains(NSSearchPathDirectory directoryKey, NSSearchPathDomainMask domainMask, BOOL expandTilde) { - static NSString *adminDir = @"Administrator"; - static NSString *appsDir = @"Applications"; - static NSString *devDir = @"Developer"; - static NSString *demosDir = @"Demos"; - static NSString *libraryDir = @"Library"; - static NSString *supportDir = @"ApplicationSupport"; - static NSString *docDir = @"Documentation"; - static NSString *fontsDir = @"Fonts"; - static NSString *frameworkDir = @"Frameworks"; - static NSString *libsDir = @"Libraries"; - static NSString *toolsDir = @"Tools"; NSMutableArray *paths = [NSMutableArray new]; NSString *path; unsigned i; @@ -1421,7 +1608,7 @@ NSSearchPathForDirectoriesInDomains(NSSearchPathDirectory directoryKey, InitialisePathUtilities(); - NSCAssert(gnustepSystemRoot!=nil,@"Path utilities without initialisation!"); + NSCAssert(gnustepMakefiles!=nil,@"Path utilities without initialisation!"); /* * The order in which we return paths is important - user must come @@ -1435,13 +1622,13 @@ NSSearchPathForDirectoriesInDomains(NSSearchPathDirectory directoryKey, if (domainMask & mask) \ { \ path = [base_dir stringByAppendingPathComponent: add_dir]; \ - if (path != nil && [paths containsObject: path] == NO) \ + if ([path length] > 0 && [paths containsObject: path] == NO) \ [paths addObject: path]; \ } #define ADD_PLATFORM_PATH(mask, add_dir) \ if (domainMask & mask) \ { \ - if (add_dir != nil && [paths containsObject: add_dir] == NO) \ + if ([add_dir length] > 0 && [paths containsObject: add_dir] == NO) \ [paths addObject: add_dir]; \ } @@ -1449,187 +1636,199 @@ if (domainMask & mask) \ { case NSAllApplicationsDirectory: { - NSString *devDemosDir; - NSString *devAppsDir; - NSString *devAdminDir; + ADD_PLATFORM_PATH(NSUserDomainMask, gnustepUserApps); + ADD_PLATFORM_PATH(NSLocalDomainMask, gnustepLocalApps); + ADD_PLATFORM_PATH(NSNetworkDomainMask, gnustepNetworkApps); + ADD_PLATFORM_PATH(NSSystemDomainMask, gnustepSystemApps); - devDemosDir = [devDir stringByAppendingPathComponent: demosDir]; - devAppsDir = [devDir stringByAppendingPathComponent: appsDir]; - devAdminDir = [devDir stringByAppendingPathComponent: adminDir]; - - ADD_PATH(NSUserDomainMask, gnustepUserRoot, appsDir); - ADD_PATH(NSUserDomainMask, gnustepUserRoot, devAppsDir); - - ADD_PATH(NSLocalDomainMask, gnustepLocalRoot, appsDir); - ADD_PATH(NSLocalDomainMask, gnustepLocalRoot, devAppsDir); - ADD_PATH(NSLocalDomainMask, gnustepLocalRoot, devAdminDir); - - ADD_PATH(NSNetworkDomainMask, gnustepNetworkRoot, appsDir); - ADD_PATH(NSNetworkDomainMask, gnustepNetworkRoot, devAppsDir); - ADD_PATH(NSNetworkDomainMask, gnustepNetworkRoot, devAdminDir); - - ADD_PATH(NSSystemDomainMask, gnustepSystemRoot, appsDir); - ADD_PATH(NSSystemDomainMask, gnustepSystemRoot, devAppsDir); - ADD_PATH(NSSystemDomainMask, gnustepSystemRoot, devAdminDir); - - ADD_PATH(NSSystemDomainMask, gnustepSystemRoot, devDemosDir); - - ADD_PLATFORM_PATH(NSLocalDomainMask, localApps); - ADD_PLATFORM_PATH(NSSystemDomainMask, platformApps); - ADD_PLATFORM_PATH(NSSystemDomainMask, osSysApps); - ADD_PLATFORM_PATH(NSSystemDomainMask, osSysAdmin); - ADD_PLATFORM_PATH(NSSystemDomainMask, platformAdmin); + ADD_PLATFORM_PATH(NSUserDomainMask, gnustepUserAdminApps); + ADD_PLATFORM_PATH(NSLocalDomainMask, gnustepLocalAdminApps); + ADD_PLATFORM_PATH(NSNetworkDomainMask, gnustepNetworkAdminApps); + ADD_PLATFORM_PATH(NSSystemDomainMask, gnustepSystemAdminApps); } break; case NSApplicationDirectory: { - ADD_PATH(NSUserDomainMask, gnustepUserRoot, appsDir); - ADD_PATH(NSLocalDomainMask, gnustepLocalRoot, appsDir); - ADD_PATH(NSNetworkDomainMask, gnustepNetworkRoot, appsDir); - ADD_PATH(NSSystemDomainMask, gnustepSystemRoot, appsDir); - - ADD_PLATFORM_PATH(NSLocalDomainMask, localApps); - ADD_PLATFORM_PATH(NSSystemDomainMask, platformApps); - ADD_PLATFORM_PATH(NSSystemDomainMask, osSysApps); + ADD_PLATFORM_PATH(NSUserDomainMask, gnustepUserApps); + ADD_PLATFORM_PATH(NSLocalDomainMask, gnustepLocalApps); + ADD_PLATFORM_PATH(NSNetworkDomainMask, gnustepNetworkApps); + ADD_PLATFORM_PATH(NSSystemDomainMask, gnustepSystemApps); } break; case NSDemoApplicationDirectory: { - NSString *devDemosDir; + ADD_PLATFORM_PATH(NSUserDomainMask, gnustepUserApps); + ADD_PLATFORM_PATH(NSLocalDomainMask, gnustepLocalApps); + ADD_PLATFORM_PATH(NSNetworkDomainMask, gnustepNetworkApps); + ADD_PLATFORM_PATH(NSSystemDomainMask, gnustepSystemApps); - devDemosDir = [devDir stringByAppendingPathComponent: demosDir]; - ADD_PATH(NSSystemDomainMask, gnustepSystemRoot, devDemosDir); + /* I imagine if ever wanted a separate Demo directory, the + * only way for this to have some meaning across filesystems + * would be as a subdirectory of Applications, as follows. + */ + /* + ADD_PATH(NSUserDomainMask, gnustepUserApps, @"Demos"); + ADD_PATH(NSLocalDomainMask, gnustepLocalApps, @"Demos"); + ADD_PATH(NSNetworkDomainMask, gnustepNetworkApps, @"Demos"); + ADD_PATH(NSSystemDomainMask, gnustepSystemApps, @"Demos"); + */ + } + break; + + case NSCoreServicesDirectory: + { + ADD_PATH(NSSystemDomainMask, gnustepSystemLibrary, @"CoreServices"); + } + break; + + case NSDesktopDirectory: + { + ADD_PATH(NSUserDomainMask, gnustepUserLibrary, @"Desktop"); } break; case NSDeveloperApplicationDirectory: { - NSString *devAppsDir; + ADD_PLATFORM_PATH(NSUserDomainMask, gnustepUserApps); + ADD_PLATFORM_PATH(NSLocalDomainMask, gnustepLocalApps); + ADD_PLATFORM_PATH(NSNetworkDomainMask, gnustepNetworkApps); + ADD_PLATFORM_PATH(NSSystemDomainMask, gnustepSystemApps); - devAppsDir = [devDir stringByAppendingPathComponent: appsDir]; - ADD_PATH(NSUserDomainMask, gnustepUserRoot, devAppsDir); - ADD_PATH(NSLocalDomainMask, gnustepLocalRoot, devAppsDir); - ADD_PATH(NSNetworkDomainMask, gnustepNetworkRoot, devAppsDir); - ADD_PATH(NSSystemDomainMask, gnustepSystemRoot, devAppsDir); + /* I imagine if ever wanted a separate Developer directory, the + * only way for this to have some meaning across filesystems + * would be as a subdirectory of Applications, as follows. + */ + /* + ADD_PATH(NSUserDomainMask, gnustepUserApps, @"Developer"); + ADD_PATH(NSLocalDomainMask, gnustepLocalApps, @"Developer"); + ADD_PATH(NSNetworkDomainMask, gnustepNetworkApps, @"Developer"); + ADD_PATH(NSSystemDomainMask, gnustepSystemApps, @"Developer"); + */ } break; case NSAdminApplicationDirectory: { - NSString *devAdminDir; - - devAdminDir = [devDir stringByAppendingPathComponent: adminDir]; - /* NSUserDomainMask - users have no Administrator directory */ - ADD_PATH(NSLocalDomainMask, gnustepLocalRoot, devAdminDir); - ADD_PATH(NSNetworkDomainMask, gnustepNetworkRoot, devAdminDir); - ADD_PATH(NSSystemDomainMask, gnustepSystemRoot, devAdminDir); - - ADD_PLATFORM_PATH(NSSystemDomainMask, osSysAdmin); - ADD_PLATFORM_PATH(NSSystemDomainMask, platformAdmin); + ADD_PLATFORM_PATH(NSUserDomainMask, gnustepUserAdminApps); + ADD_PLATFORM_PATH(NSLocalDomainMask, gnustepLocalAdminApps); + ADD_PLATFORM_PATH(NSNetworkDomainMask, gnustepNetworkAdminApps); + ADD_PLATFORM_PATH(NSSystemDomainMask, gnustepSystemAdminApps); } break; case NSAllLibrariesDirectory: { - ADD_PATH(NSUserDomainMask, gnustepUserRoot, libraryDir); - ADD_PATH(NSLocalDomainMask, gnustepLocalRoot, libraryDir); - ADD_PATH(NSNetworkDomainMask, gnustepNetworkRoot, libraryDir); - ADD_PATH(NSSystemDomainMask, gnustepSystemRoot, libraryDir); - - ADD_PLATFORM_PATH(NSLocalDomainMask, localResources); - ADD_PLATFORM_PATH(NSSystemDomainMask, platformResources); + ADD_PLATFORM_PATH(NSUserDomainMask, gnustepUserLibrary); + ADD_PLATFORM_PATH(NSLocalDomainMask, gnustepLocalLibrary); + ADD_PLATFORM_PATH(NSNetworkDomainMask, gnustepNetworkLibrary); + ADD_PLATFORM_PATH(NSSystemDomainMask, gnustepSystemLibrary); } break; case NSLibraryDirectory: { - ADD_PATH(NSUserDomainMask, gnustepUserRoot, libraryDir); - ADD_PATH(NSLocalDomainMask, gnustepLocalRoot, libraryDir); - ADD_PATH(NSNetworkDomainMask, gnustepNetworkRoot, libraryDir); - ADD_PATH(NSSystemDomainMask, gnustepSystemRoot, libraryDir); - - ADD_PLATFORM_PATH(NSLocalDomainMask, localResources); - ADD_PLATFORM_PATH(NSSystemDomainMask, platformResources); + ADD_PLATFORM_PATH(NSUserDomainMask, gnustepUserLibrary); + ADD_PLATFORM_PATH(NSLocalDomainMask, gnustepLocalLibrary); + ADD_PLATFORM_PATH(NSNetworkDomainMask, gnustepNetworkLibrary); + ADD_PLATFORM_PATH(NSSystemDomainMask, gnustepSystemLibrary); } break; case NSDeveloperDirectory: { - ADD_PATH(NSUserDomainMask, gnustepUserRoot, devDir); - ADD_PATH(NSLocalDomainMask, gnustepLocalRoot, devDir); - ADD_PATH(NSNetworkDomainMask, gnustepNetworkRoot, devDir); - ADD_PATH(NSSystemDomainMask, gnustepSystemRoot, devDir); + /* The only way of having a Developer directory is as a + * sub-dir of Library. + */ + ADD_PATH(NSUserDomainMask, gnustepUserLibrary, @"Developer"); + ADD_PATH(NSLocalDomainMask, gnustepLocalLibrary, @"Developer"); + ADD_PATH(NSNetworkDomainMask, gnustepNetworkLibrary, @"Developer"); + ADD_PATH(NSSystemDomainMask, gnustepSystemLibrary, @"Developer"); } break; case NSUserDirectory: { - if (domainMask & NSUserDomainMask) - { - [paths addObject: gnustepUserRoot]; - } + /* This is the directory in which user directories are located. + * You can not have user directories in your own user directory, + * so NSUserDomainMask will always return ''. + */ + ADD_PLATFORM_PATH(NSLocalDomainMask, gnustepLocalUsersDir); + ADD_PLATFORM_PATH(NSNetworkDomainMask, gnustepNetworkUsersDir); + ADD_PLATFORM_PATH(NSSystemDomainMask, gnustepSystemUsersDir); } break; case NSDocumentationDirectory: { - NSString *gsdocDir; + ADD_PLATFORM_PATH(NSUserDomainMask, gnustepUserDocumentation); + ADD_PLATFORM_PATH(NSLocalDomainMask, gnustepLocalDocumentation); + ADD_PLATFORM_PATH(NSNetworkDomainMask, gnustepNetworkDocumentation); + ADD_PLATFORM_PATH(NSSystemDomainMask, gnustepSystemDocumentation); + } + break; - gsdocDir = [libraryDir stringByAppendingPathComponent: docDir]; - ADD_PATH(NSUserDomainMask, gnustepUserRoot, gsdocDir); - ADD_PATH(NSLocalDomainMask, gnustepLocalRoot, gsdocDir); - ADD_PATH(NSNetworkDomainMask, gnustepNetworkRoot, gsdocDir); - ADD_PATH(NSSystemDomainMask, gnustepSystemRoot, gsdocDir); + case NSDocumentDirectory: + { + ADD_PATH(NSUserDomainMask, gnustepUserLibrary, @"Document"); + ADD_PATH(NSLocalDomainMask, gnustepLocalLibrary, @"Document"); + ADD_PATH(NSNetworkDomainMask, gnustepNetworkLibrary, @"Document"); + ADD_PATH(NSSystemDomainMask, gnustepSystemLibrary, @"Document"); + } + break; + + case NSCachesDirectory: + { + /* Uff - at the moment the only place to put Caches seems to + * be Library. Unfortunately under GNU/Linux Library will + * end up in /usr/lib/GNUstep which could be mounted + * read-only! + */ + ADD_PATH(NSUserDomainMask, gnustepUserLibrary, @"Caches"); + ADD_PATH(NSLocalDomainMask, gnustepLocalLibrary, @"Caches"); + ADD_PATH(NSNetworkDomainMask, gnustepNetworkLibrary, @"Caches"); + ADD_PATH(NSSystemDomainMask, gnustepSystemLibrary, @"Caches"); + } + break; + + case NSApplicationSupportDirectory: + { + ADD_PATH(NSUserDomainMask, gnustepUserLibrary, @"ApplicationSupport"); + ADD_PATH(NSLocalDomainMask, gnustepLocalLibrary, + @"ApplicationSupport"); + ADD_PATH(NSNetworkDomainMask, gnustepNetworkLibrary, + @"ApplicationSupport"); + ADD_PATH(NSSystemDomainMask, gnustepSystemLibrary, + @"ApplicationSupport"); } break; /* Now the GNUstep additions */ - case GSApplicationSupportDirectory: - { - NSString *appSupDir; - - appSupDir = [libraryDir stringByAppendingPathComponent: supportDir]; - ADD_PATH(NSUserDomainMask, gnustepUserRoot, appSupDir); - ADD_PATH(NSLocalDomainMask, gnustepLocalRoot, appSupDir); - ADD_PATH(NSNetworkDomainMask, gnustepNetworkRoot, appSupDir); - ADD_PATH(NSSystemDomainMask, gnustepSystemRoot, appSupDir); - } - break; - case GSFrameworksDirectory: { - NSString *frameDir; - - frameDir = [libraryDir stringByAppendingPathComponent: frameworkDir]; - ADD_PATH(NSUserDomainMask, gnustepUserRoot, frameDir); - ADD_PATH(NSLocalDomainMask, gnustepLocalRoot, frameDir); - ADD_PATH(NSNetworkDomainMask, gnustepNetworkRoot, frameDir); - ADD_PATH(NSSystemDomainMask, gnustepSystemRoot, frameDir); + ADD_PATH(NSUserDomainMask, gnustepUserLibrary, @"Frameworks"); + ADD_PATH(NSLocalDomainMask, gnustepLocalLibrary, @"Frameworks"); + ADD_PATH(NSNetworkDomainMask, gnustepNetworkLibrary, @"Frameworks"); + ADD_PATH(NSSystemDomainMask, gnustepSystemLibrary, @"Frameworks"); } break; case GSFontsDirectory: { - NSString *fontDir; - - fontDir = [libraryDir stringByAppendingPathComponent: fontsDir]; - ADD_PATH(NSUserDomainMask, gnustepUserRoot, fontDir); - ADD_PATH(NSLocalDomainMask, gnustepLocalRoot, fontDir); - ADD_PATH(NSNetworkDomainMask, gnustepNetworkRoot, fontDir); - ADD_PATH(NSSystemDomainMask, gnustepSystemRoot, fontDir); + ADD_PATH(NSUserDomainMask, gnustepUserLibrary, @"Fonts"); + ADD_PATH(NSLocalDomainMask, gnustepLocalLibrary, @"Fonts"); + ADD_PATH(NSNetworkDomainMask, gnustepNetworkLibrary, @"Fonts"); + ADD_PATH(NSSystemDomainMask, gnustepSystemLibrary, @"Fonts"); } break; case GSLibrariesDirectory: { - NSString *gslibsDir; NSString *full = nil; NSString *part = nil; - gslibsDir = [libraryDir stringByAppendingPathComponent: libsDir]; - if ([gnustep_flattened boolValue] == NO + if ([gnustep_is_flattened boolValue] == NO && gnustep_target_cpu != nil && gnustep_target_os != nil) { part = [gnustep_target_cpu stringByAppendingPathComponent: @@ -1637,27 +1836,26 @@ if (domainMask & mask) \ if (library_combo != nil) { full = [part stringByAppendingPathComponent: library_combo]; - full = [gslibsDir stringByAppendingPathComponent: full]; } - part = [gslibsDir stringByAppendingPathComponent: part]; } - ADD_PATH(NSUserDomainMask, gnustepUserRoot, gslibsDir); - if (full) ADD_PATH(NSUserDomainMask, gnustepUserRoot, full); - if (part) ADD_PATH(NSUserDomainMask, gnustepUserRoot, part); - ADD_PATH(NSLocalDomainMask, gnustepLocalRoot, gslibsDir); - if (full) ADD_PATH(NSLocalDomainMask, gnustepLocalRoot, full); - if (part) ADD_PATH(NSLocalDomainMask, gnustepLocalRoot, part); - ADD_PATH(NSNetworkDomainMask, gnustepNetworkRoot, gslibsDir); - if (full) ADD_PATH(NSNetworkDomainMask, gnustepNetworkRoot, full); - if (part) ADD_PATH(NSNetworkDomainMask, gnustepNetworkRoot, part); - ADD_PATH(NSSystemDomainMask, gnustepSystemRoot, gslibsDir); - if (full) ADD_PATH(NSSystemDomainMask, gnustepSystemRoot, full); - if (part) ADD_PATH(NSSystemDomainMask, gnustepSystemRoot, part); + ADD_PLATFORM_PATH(NSUserDomainMask, gnustepUserLibraries); + if (full) ADD_PATH(NSUserDomainMask, gnustepUserLibraries, full); + if (part) ADD_PATH(NSUserDomainMask, gnustepUserLibraries, part); - ADD_PLATFORM_PATH(NSLocalDomainMask, localLibs); - ADD_PLATFORM_PATH(NSSystemDomainMask, platformLibs); - ADD_PLATFORM_PATH(NSSystemDomainMask, osSysLibs); + ADD_PLATFORM_PATH(NSLocalDomainMask, gnustepLocalLibraries); + if (full) ADD_PATH(NSLocalDomainMask, gnustepLocalLibraries, full); + if (part) ADD_PATH(NSLocalDomainMask, gnustepLocalLibraries, part); + + ADD_PLATFORM_PATH(NSNetworkDomainMask, gnustepNetworkLibraries); + if (full) + ADD_PATH(NSNetworkDomainMask, gnustepNetworkLibraries, full); + if (part) + ADD_PATH(NSNetworkDomainMask, gnustepNetworkLibraries, part); + + ADD_PLATFORM_PATH(NSSystemDomainMask, gnustepSystemLibraries); + if (full) ADD_PATH(NSSystemDomainMask, gnustepSystemLibraries, full); + if (part) ADD_PATH(NSSystemDomainMask, gnustepSystemLibraries, part); } break; @@ -1666,7 +1864,7 @@ if (domainMask & mask) \ NSString *full = nil; NSString *part = nil; - if ([gnustep_flattened boolValue] == NO + if ([gnustep_is_flattened boolValue] == NO && gnustep_target_cpu != nil && gnustep_target_os != nil) { part = [gnustep_target_cpu stringByAppendingPathComponent: @@ -1674,35 +1872,67 @@ if (domainMask & mask) \ if (library_combo != nil) { full = [part stringByAppendingPathComponent: library_combo]; - full = [toolsDir stringByAppendingPathComponent: full]; } - part = [toolsDir stringByAppendingPathComponent: part]; } - ADD_PATH(NSUserDomainMask, gnustepUserRoot, toolsDir); - if (full) ADD_PATH(NSUserDomainMask, gnustepUserRoot, full); - if (part) ADD_PATH(NSUserDomainMask, gnustepUserRoot, part); - ADD_PATH(NSLocalDomainMask, gnustepLocalRoot, toolsDir); - if (full) ADD_PATH(NSLocalDomainMask, gnustepLocalRoot, full); - if (part) ADD_PATH(NSLocalDomainMask, gnustepLocalRoot, part); - ADD_PATH(NSNetworkDomainMask, gnustepNetworkRoot, toolsDir); - if (full) ADD_PATH(NSNetworkDomainMask, gnustepNetworkRoot, full); - if (part) ADD_PATH(NSNetworkDomainMask, gnustepNetworkRoot, part); - ADD_PATH(NSSystemDomainMask, gnustepSystemRoot, toolsDir); - if (full) ADD_PATH(NSSystemDomainMask, gnustepSystemRoot, full); - if (part) ADD_PATH(NSSystemDomainMask, gnustepSystemRoot, part); + ADD_PLATFORM_PATH(NSUserDomainMask, gnustepUserTools); + if (full) ADD_PATH(NSUserDomainMask, gnustepUserTools, full); + if (part) ADD_PATH(NSUserDomainMask, gnustepUserTools, part); - ADD_PLATFORM_PATH(NSLocalDomainMask, localApps); - ADD_PLATFORM_PATH(NSSystemDomainMask, platformApps); - ADD_PLATFORM_PATH(NSSystemDomainMask, osSysApps); - ADD_PLATFORM_PATH(NSSystemDomainMask, platformAdmin); - ADD_PLATFORM_PATH(NSSystemDomainMask, osSysAdmin); + ADD_PLATFORM_PATH(NSLocalDomainMask, gnustepLocalTools); + if (full) ADD_PATH(NSLocalDomainMask, gnustepLocalTools, full); + if (part) ADD_PATH(NSLocalDomainMask, gnustepLocalTools, part); + + ADD_PLATFORM_PATH(NSNetworkDomainMask, gnustepNetworkTools); + if (full) ADD_PATH(NSNetworkDomainMask, gnustepNetworkTools, full); + if (part) ADD_PATH(NSNetworkDomainMask, gnustepNetworkTools, part); + + ADD_PLATFORM_PATH(NSSystemDomainMask, gnustepSystemTools); + if (full) ADD_PATH(NSSystemDomainMask, gnustepSystemTools, full); + if (part) ADD_PATH(NSSystemDomainMask, gnustepSystemTools, part); } break; - case GSPreferencesDirectory: + case GSAdminToolsDirectory: { - // Not used + NSString *full = nil; + NSString *part = nil; + + if ([gnustep_is_flattened boolValue] == NO + && gnustep_target_cpu != nil && gnustep_target_os != nil) + { + part = [gnustep_target_cpu stringByAppendingPathComponent: + gnustep_target_os]; + if (library_combo != nil) + { + full = [part stringByAppendingPathComponent: library_combo]; + } + } + + ADD_PLATFORM_PATH(NSUserDomainMask, gnustepUserAdminTools); + if (full) ADD_PATH(NSUserDomainMask, gnustepUserAdminTools, full); + if (part) ADD_PATH(NSUserDomainMask, gnustepUserAdminTools, part); + + ADD_PLATFORM_PATH(NSLocalDomainMask, gnustepLocalAdminTools); + if (full) ADD_PATH(NSLocalDomainMask, gnustepLocalAdminTools, full); + if (part) ADD_PATH(NSLocalDomainMask, gnustepLocalAdminTools, part); + + ADD_PLATFORM_PATH(NSNetworkDomainMask, gnustepNetworkAdminTools); + if (full) ADD_PATH(NSNetworkDomainMask, gnustepNetworkAdminTools, full); + if (part) ADD_PATH(NSNetworkDomainMask, gnustepNetworkAdminTools, part); + + ADD_PLATFORM_PATH(NSSystemDomainMask, gnustepSystemAdminTools); + if (full) ADD_PATH(NSSystemDomainMask, gnustepSystemAdminTools, full); + if (part) ADD_PATH(NSSystemDomainMask, gnustepSystemAdminTools, part); + } + break; + + case GSWebApplicationsDirectory: + { + ADD_PLATFORM_PATH(NSUserDomainMask, gnustepUserWebApps); + ADD_PLATFORM_PATH(NSLocalDomainMask, gnustepLocalWebApps); + ADD_PLATFORM_PATH(NSNetworkDomainMask, gnustepNetworkWebApps); + ADD_PLATFORM_PATH(NSSystemDomainMask, gnustepSystemWebApps); } break; } @@ -1715,17 +1945,10 @@ if (domainMask & mask) \ { path = [paths objectAtIndex: i]; - /* remove paths which don't exist on this system */ - if ([MGR() fileExistsAtPath: path] == NO) - { - [paths removeObjectAtIndex: i]; - i--; - count--; - } - else if (expandTilde == YES) + if (expandTilde == YES) { [paths replaceObjectAtIndex: i - withObject: [path stringByExpandingTildeInPath]]; + withObject: [path stringByExpandingTildeInPath]]; } else { diff --git a/Source/NSPipe.m b/Source/NSPipe.m index b9c630e05..139fdd1ac 100644 --- a/Source/NSPipe.m +++ b/Source/NSPipe.m @@ -18,7 +18,8 @@ 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., 51 Franklin Street, Fifth Floor, Boston, MA 02111 USA. + Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02111 USA. $Date$ $Revision$ */ @@ -28,6 +29,7 @@ #include "Foundation/NSObject.h" #include "Foundation/NSFileHandle.h" #include "Foundation/NSDebug.h" +#include "GSPrivate.h" #ifdef HAVE_UNISTD_H #include #endif @@ -77,7 +79,7 @@ } else { - NSLog(@"Failed to create pipe ... %s", GSLastErrorStr(errno)); + NSLog(@"Failed to create pipe ... %@", [NSError _last]); DESTROY(self); } #else @@ -95,6 +97,11 @@ writeHandle = [[NSFileHandle alloc] initWithNativeHandle: writeh closeOnDealloc: YES]; } + else + { + NSLog(@"Failed to create pipe ... %@", [NSError _last]); + DESTROY(self); + } #endif } return self; diff --git a/Source/NSPort.m b/Source/NSPort.m index eea40bef1..cf8bece84 100644 --- a/Source/NSPort.m +++ b/Source/NSPort.m @@ -18,7 +18,8 @@ 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., 51 Franklin Street, Fifth Floor, Boston, MA 02111 USA. + Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02111 USA. NSPort class reference $Date$ $Revision$ @@ -27,6 +28,7 @@ #include "config.h" #include "Foundation/NSException.h" #include "Foundation/NSString.h" +#include "Foundation/NSNotification.h" #include "Foundation/NSNotificationQueue.h" #include "Foundation/NSPort.h" #include "Foundation/NSPortCoder.h" @@ -53,8 +55,8 @@ */ NSString * const NSPortTimeoutException = @"NSPortTimeoutException"; -Class NSPort_abstract_class; -Class NSPort_concrete_class; +static Class NSPort_abstract_class; +static Class NSPort_concrete_class; + (id) allocWithZone: (NSZone*)aZone { diff --git a/Source/NSPortNameServer.m b/Source/NSPortNameServer.m index a9745bd17..e23d1d35b 100644 --- a/Source/NSPortNameServer.m +++ b/Source/NSPortNameServer.m @@ -18,8 +18,8 @@ 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., 51 Franklin Street, Fifth Floor, Boston, - MA 02111 USA. + Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02111 USA. NSPortNameServer class reference $Date$ $Revision$ diff --git a/Source/NSPredicate.m b/Source/NSPredicate.m index aaa415a52..31fe90094 100644 --- a/Source/NSPredicate.m +++ b/Source/NSPredicate.m @@ -1435,11 +1435,11 @@ notPredicateWithSubpredicate: [self parseNot]]; } - if ([self scanPredicateKeyword:@"TRUEPREDICATE"]) + if ([self scanPredicateKeyword: @"TRUEPREDICATE"]) { return [NSPredicate predicateWithValue: YES]; } - if ([self scanPredicateKeyword:@"FALSEPREDICATE"]) + if ([self scanPredicateKeyword: @"FALSEPREDICATE"]) { return [NSPredicate predicateWithValue: NO]; } @@ -1451,7 +1451,7 @@ { NSPredicate *l = [self parseNot]; - while ([self scanPredicateKeyword:@"OR"]) + while ([self scanPredicateKeyword: @"OR"]) { NSPredicate *r = [self parseNot]; @@ -1483,7 +1483,7 @@ } else { - l = [NSCompoundPredicate andPredicateWithSubpredicates: + l = [NSCompoundPredicate orPredicateWithSubpredicates: [NSArray arrayWithObjects: l, r, nil]]; } } @@ -1771,7 +1771,7 @@ [args addObject: [self parseExpression]]; } - if (![self scanString:@")" intoString:NULL]) + if (![self scanString: @")" intoString: NULL]) { [NSException raise: NSInvalidArgumentException format: @"Missing ) in function arguments"]; diff --git a/Source/NSProcessInfo.m b/Source/NSProcessInfo.m index d26ba0d9e..6a0f335df 100644 --- a/Source/NSProcessInfo.m +++ b/Source/NSProcessInfo.m @@ -71,6 +71,9 @@ #ifdef HAVE_SYS_FCNTL_H #include #endif +#ifdef HAVE_SYS_UTSNAME_H +#include +#endif #ifdef HAVE_KVM_ENV #include @@ -85,7 +88,7 @@ #undef id #endif -#include "GSConfig.h" +#include "GNUstepBase/GSConfig.h" #include "Foundation/NSString.h" #include "Foundation/NSArray.h" #include "Foundation/NSBundle.h" @@ -97,6 +100,7 @@ #include "Foundation/NSAutoreleasePool.h" #include "Foundation/NSHost.h" #include "Foundation/NSLock.h" +#include "Foundation/NSDebug.h" #include "GNUstepBase/GSCategories.h" #include "GSPrivate.h" @@ -194,16 +198,22 @@ static NSArray *_gnu_arguments = nil; // Dictionary of environment vars and their values static NSMutableDictionary *_gnu_environment = nil; +// The operating system we are using. +static unsigned int _operatingSystem = 0; +static NSString *_operatingSystemName = nil; +static NSString *_operatingSystemVersion = nil; + // Array of debug levels set. static NSMutableSet *_debug_set = nil; // Flag to indicate that fallbackInitialisation was executed. static BOOL fallbackInitialisation = NO; + /************************************************************************* *** Implementing the gnustep_base_user_main function *************************************************************************/ -void +static void _gnu_process_args(int argc, char *argv[], char *env[]) { CREATE_AUTORELEASE_POOL(arp); @@ -252,7 +262,7 @@ _gnu_process_args(int argc, char *argv[], char *env[]) objc_free(buffer); } } - tmp = [arg0 UTF8String]; + tmp = [arg0 cStringUsingEncoding: [NSString defaultCStringEncoding]]; _gnu_arg_zero = (char*)objc_malloc(strlen(tmp) + 1); strcpy(_gnu_arg_zero, tmp); #else @@ -265,6 +275,19 @@ _gnu_process_args(int argc, char *argv[], char *env[]) /* Getting the process name */ IF_NO_GC(RELEASE(_gnu_processName)); _gnu_processName = [arg0 lastPathComponent]; +#if defined(__MINGW32__) + /* On windows we remove any .exe extension for consistency with app names + * under unix + */ + { + NSString *e = [_gnu_processName pathExtension]; + + if (e != nil && [e caseInsensitiveCompare: @"EXE"] == NSOrderedSame) + { + _gnu_processName = [_gnu_processName stringByDeletingPathExtension]; + } + } +#endif IF_NO_GC(RETAIN(_gnu_processName)); /* Copy the argument list */ @@ -307,6 +330,7 @@ _gnu_process_args(int argc, char *argv[], char *env[]) NSMutableSet *mySet; id obj_argv[argc]; int added = 1; + NSStringEncoding enc = GSPrivateDefaultCStringEncoding(); mySet = [NSMutableSet new]; @@ -315,7 +339,7 @@ _gnu_process_args(int argc, char *argv[], char *env[]) for (i = 1; i < argc; i++) { - str = [NSString stringWithCString: argv[i]]; + str = [NSString stringWithCString: argv[i] encoding: enc]; if ([str hasPrefix: @"--GNU-Debug="]) [mySet addObject: [str substringFromIndex: 12]]; @@ -335,6 +359,7 @@ _gnu_process_args(int argc, char *argv[], char *env[]) { NSMutableArray *keys = [NSMutableArray new]; NSMutableArray *values = [NSMutableArray new]; + NSStringEncoding enc = GSPrivateDefaultCStringEncoding(); #if defined(__MINGW32__) if (fallbackInitialisation == NO) @@ -398,8 +423,10 @@ _gnu_process_args(int argc, char *argv[], char *env[]) strcpy(buf, env[i]); cp = &buf[cp - env[i]]; *cp++ = '\0'; - [keys addObject: [NSString stringWithCString: buf]]; - [values addObject: [NSString stringWithCString: cp]]; + [keys addObject: + [NSString stringWithCString: buf encoding: enc]]; + [values addObject: + [NSString stringWithCString: cp encoding: enc]]; } i++; } @@ -874,9 +901,6 @@ int main(int argc, char *argv[], char *env[]) #endif /* HAS_LOAD_METHOD && HAS_PROCFS */ -/** - * Returns the shared NSProcessInfo object for the current process. - */ + (NSProcessInfo *) processInfo { // Check if the main() function was successfully called @@ -895,42 +919,16 @@ int main(int argc, char *argv[], char *env[]) return _gnu_sharedProcessInfoObject; } -/** - * Returns an array containing the arguments supplied to start this - * process.
- * NB. In GNUstep, any arguments of the form --GNU-Debug=... - * are not included in this array ... they are part of the - * debug mechanism, and are hidden so that setting debug variables - * will not effect the normal operation of the program.
- * Please note, the special --GNU-Debug=... syntax differs from - * that which is used to specify values for the [NSUserDefaults] system.
- * User defaults are set on the command line by specifying the default name - * (with a leading hyphen) as one argument, and the default value as the - * following argument. The arguments used to set user defaults are - * present in the array returned by this method. - */ - (NSArray *) arguments { return _gnu_arguments; } -/** - * Returns a dictionary giving the environment variables which were - * provided for the process to use. - */ - (NSDictionary *) environment { return _gnu_environment; } -/** - * Returns a string which may be used as a globally unique identifier.
- * The string contains the host name, the process ID, a timestamp and a - * counter.
- * The first three values identify the process in which the string is - * generated, while the fourth ensures that multiple strings generated - * within the same process are unique. - */ - (NSString *) globallyUniqueString { static unsigned long counter = 0; @@ -958,9 +956,6 @@ int main(int argc, char *argv[], char *env[]) host, pid, start, count]; } -/** - * Returns the name of the machine on which this process is running. - */ - (NSString *) hostName { if (!_gnu_hostName) @@ -970,103 +965,169 @@ int main(int argc, char *argv[], char *env[]) return _gnu_hostName; } -/** - * Return a number representing the operating system type.
- * The known types are listed in the header file, but not all of the - * listed types are actually implemented ... some are present for - * MacOS-X compatibility only.
- * - * NSWindowsNTOperatingSystem - used for windows NT, 2000, XP - * NSWindows95OperatingSystem - probably never to be implemented - * NSSolarisOperatingSystem - not yet recognised - * NSHPUXOperatingSystem - not implemented - * NSMACHOperatingSystem - perhaps the HURD in future? - * NSSunOSOperatingSystem - probably never to be implemented - * NSOSF1OperatingSystem - probably never to be implemented - * NSGNULinuxOperatingSystem - the GNUstep 'standard' - * NSBSDOperatingSystem - BSD derived operating systems - * NSCygwinOperatingSystem - cygwin unix-like environment - * - */ +static void determineOperatingSystem() +{ + if (_operatingSystem == 0) + { + NSString *os = nil; + BOOL parseOS = YES; + +#if defined(__MINGW32__) + OSVERSIONINFOW osver; + + osver.dwOSVersionInfoSize = sizeof(osver); + GetVersionExW (&osver); + /* Hmm, we could use this to determine operating system version, but + * that would not distinguish between mingw and cygwin, so we just + * use the information from NSBundle and only get the version info + * here. + */ + _operatingSystemVersion = [[NSString alloc] initWithFormat: @"%d.%d", + osver.dwMajorVersion, osver.dwMinorVersion]; +#else +#if defined(HAVE_SYS_UTSNAME_H) + struct utsname uts; + + /* The system supports uname, so we can use it rather than the + * value determined at configure/compile time. + * That's good if the binary is running on a system other than + * the one it was built for (rare, but can happen). + */ + if (uname(&uts) == 0) + { + os = [NSString stringWithCString: uts.sysname encoding: [NSString defaultCStringEncoding]]; + os = [os lowercaseString]; + /* Get the operating system version ... usually the version string + * is pretty horrible, and the kernel release string actually + * makes more sense. + */ + _operatingSystemVersion = [[NSString alloc] + initWithCString: uts.release + encoding: [NSString defaultCStringEncoding]]; + + /* Hack for sunos/solaris ... sunos version 5 is solaris + */ + if ([os isEqualToString: @"sunos"] == YES + && [_operatingSystemVersion intValue] > 4) + { + os = @"solaris"; + } + } +#endif /* HAVE_SYS_UTSNAME_H */ +#endif /* __MINGW32__ */ + + if (_operatingSystemVersion == nil) + { + NSWarnFLog(@"Unable to determine system version, using 0.0"); + _operatingSystemVersion = @"0.0"; + } + + while (parseOS == YES) + { + NSString *fallback = [NSBundle _gnustep_target_os]; + + if (os == nil) + { + os = fallback; + } + parseOS = NO; + + if ([os hasPrefix: @"linux"] == YES) + { + _operatingSystemName = @"GSGNULinuxOperatingSystem"; + _operatingSystem = GSGNULinuxOperatingSystem; + } + else if ([os hasPrefix: @"mingw"] == YES) + { + _operatingSystemName = @"NSWindowsNTOperatingSystem"; + _operatingSystem = NSWindowsNTOperatingSystem; + } + else if ([os isEqualToString: @"cygwin"] == YES) + { + _operatingSystemName = @"GSCygwinOperatingSystem"; + _operatingSystem = GSCygwinOperatingSystem; + } + else if ([os hasPrefix: @"bsd"] == YES + || [os hasPrefix: @"freebsd"] == YES + || [os hasPrefix: @"netbsd"] == YES + || [os hasPrefix: @"openbsd"] == YES) + { + _operatingSystemName = @"GSBSDOperatingSystem"; + _operatingSystem = GSBSDOperatingSystem; + } + else if ([os hasPrefix: @"beos"] == YES) + { + _operatingSystemName = @"GSBeOperatingSystem"; + _operatingSystem = GSBeOperatingSystem; + } + else if ([os hasPrefix: @"darwin"] == YES) + { + _operatingSystemName = @"NSMACHOperatingSystem"; + _operatingSystem = NSMACHOperatingSystem; + } + else if ([os hasPrefix: @"solaris"] == YES) + { + _operatingSystemName = @"NSSolarisOperatingSystem"; + _operatingSystem = NSSolarisOperatingSystem; + } + else if ([os hasPrefix: @"hpux"] == YES) + { + _operatingSystemName = @"NSHPUXOperatingSystem"; + _operatingSystem = NSHPUXOperatingSystem; + } + else if ([os hasPrefix: @"sunos"] == YES) + { + _operatingSystemName = @"NSSunOSOperatingSystem"; + _operatingSystem = NSSunOSOperatingSystem; + } + else if ([os hasPrefix: @"osf"] == YES) + { + _operatingSystemName = @"NSOSF1OperatingSystem"; + _operatingSystem = NSOSF1OperatingSystem; + } + if (_operatingSystem == 0 && [os isEqual: fallback] == NO) + { + os = fallback; + parseOS = YES; // Try again with fallback + } + } + + if (_operatingSystem == 0) + { + NSWarnFLog(@"Unable to determine O/S ... assuming GNU/Linux"); + _operatingSystemName = @"GSGNULinuxOperatingSystem"; + _operatingSystem = GSGNULinuxOperatingSystem; + } + } +} + - (unsigned int) operatingSystem { - static unsigned int os = 0; - - if (os == 0) + if (_operatingSystem == 0) { - NSString *n = [self operatingSystemName]; - - if ([n isEqualToString: @"linux-gnu"] == YES) - { - os = NSGNULinuxOperatingSystem; - } - else if ([n hasPrefix: @"mingw"] == YES) - { - os = NSWindowsNTOperatingSystem; - } - else if ([n isEqualToString: @"cygwin"] == YES) - { - os = NSCygwinOperatingSystem; - } - else if ([n hasPrefix: @"bsd"] == YES) - { - os = NSBSDOperatingSystem; - } - else if ([n hasPrefix: @"freebsd"] == YES) - { - os = NSBSDOperatingSystem; - } - else if ([n hasPrefix: @"netbsd"] == YES) - { - os = NSBSDOperatingSystem; - } - else if ([n hasPrefix: @"openbsd"] == YES) - { - os = NSBSDOperatingSystem; - } - else if ([n isEqualToString: @"beos"] == YES) - { - os = NSBeOperatingSystem; - } - else if ([n hasPrefix: @"darwin"] == YES) - { - os = NSMACHOperatingSystem; - } - else if ([n hasPrefix: @"solaris"] == YES) - { - os = NSSolarisOperatingSystem; - } - else if ([n hasPrefix: @"hpux"] == YES) - { - os = NSHPUXOperatingSystem; - } - else - { - NSLog(@"Unable to determine O/S ... assuming GNU/Linux"); - os = NSGNULinuxOperatingSystem; - } + determineOperatingSystem(); } - return os; + return _operatingSystem; } -/** - * Returns the name of the operating system in use. - */ - (NSString*) operatingSystemName { - static NSString *os = nil; - - if (os == nil) + if (_operatingSystemName == 0) { - os = [[NSBundle _gnustep_target_os] copy]; + determineOperatingSystem(); } - return os; + return _operatingSystemName; +} + +- (NSString *) operatingSystemVersionString +{ + if (_operatingSystemVersion == nil) + { + determineOperatingSystem(); + } + return _operatingSystemVersion; } -/** - * Returns the process identifier number which identifies this process - * on this machine. - */ - (int) processIdentifier { int pid; @@ -1079,19 +1140,11 @@ int main(int argc, char *argv[], char *env[]) return pid; } -/** - * Returns the process name for this process. This may have been set using - * the -setProcessName: method, or may be the default process name (the - * file name of the binary being executed). - */ - (NSString *) processName { return _gnu_processName; } -/** - * Change the name of the current process to newName. - */ - (void) setProcessName: (NSString *)newName { if (newName && [newName length]) { @@ -1103,21 +1156,10 @@ int main(int argc, char *argv[], char *env[]) @end -/** - * Provides GNUstep-specific methods for controlled debug logging (a GNUstep - * facility) and an internal/developer-related method. - */ @implementation NSProcessInfo (GNUstep) static BOOL debugTemporarilyDisabled = NO; -/** - * Fallback method. The developer must call this method to initialize - * the NSProcessInfo system if none of the system-specific hacks to - * auto-initialize it are working.
- * It should also be safe to call this method to override the effects - * of the automatic initialisation. - */ + (void) initializeWithArguments: (char**)argv count: (int)argc environment: (char**)env @@ -1128,11 +1170,6 @@ static BOOL debugTemporarilyDisabled = NO; [gnustep_global_lock unlock]; } -/** - * Returns a indication of whether debug logging is enabled. - * This returns YES unless a call to -setDebugLoggingEnabled: has - * been used to turn logging off. - */ - (BOOL) debugLoggingEnabled { if (debugTemporarilyDisabled == YES) @@ -1145,23 +1182,11 @@ static BOOL debugTemporarilyDisabled = NO; } } -/** - * This method returns a set of debug levels set using the - * --GNU-Debug=... command line option and/or the GNU-Debug - * user default.
- * You can modify this set to change the debug logging under - * your programs control ... but such modifications are not - * thread-safe. - */ - (NSMutableSet*) debugSet { return _debug_set; } -/** - * This method permits you to turn all debug logging on or off - * without modifying the set of debug levels in use. - */ - (void) setDebugLoggingEnabled: (BOOL)flag { if (flag == NO) @@ -1174,11 +1199,6 @@ static BOOL debugTemporarilyDisabled = NO; } } -/** - * Set the file to which NSLog output should be directed.
- * Returns YES on success, NO on failure.
- * By default logging goes to standard error. - */ - (BOOL) setLogFile: (NSString*)path { extern int _NSLogDescriptor; @@ -1202,12 +1222,6 @@ static BOOL debugTemporarilyDisabled = NO; } @end -/** - * Function for rapid testing to see if a debug level is set.
- * This is used by the debugging macros.
- * If debug logging has been turned off, this returns NO even if - * the specified level exists in the set of debug levels. - */ BOOL GSDebugSet(NSString *level) { static IMP debugImp = 0; @@ -1233,9 +1247,8 @@ BOOL GSDebugSet(NSString *level) return YES; } - BOOL -GSEnvironmentFlag(const char *name, BOOL def) +GSPrivateEnvironmentFlag(const char *name, BOOL def) { const char *c = getenv(name); BOOL a = def; @@ -1262,12 +1275,8 @@ GSEnvironmentFlag(const char *name, BOOL def) return a; } -/** - * Used by NSException uncaught exception handler - must not call any - * methods/functions which might cause a recursive exception. - */ const char* -GSArgZero(void) +GSPrivateArgZero() { if (_gnu_arg_zero == 0) return ""; @@ -1275,4 +1284,3 @@ GSArgZero(void) return _gnu_arg_zero; } - diff --git a/Source/NSPropertyList.m b/Source/NSPropertyList.m index ba0f26315..2da4f3792 100644 --- a/Source/NSPropertyList.m +++ b/Source/NSPropertyList.m @@ -44,19 +44,281 @@ #include "Foundation/NSUserDefaults.h" #include "Foundation/NSValue.h" #include "Foundation/NSDebug.h" +#include "Foundation/NSXMLParser.h" #include "GNUstepBase/Unicode.h" #include "GSPrivate.h" extern BOOL GSScanDouble(unichar*, unsigned, double*); -@class GSMutableArray; -@interface GSMutableArray : NSObject // Help the compiler -@end @class GSMutableDictionary; @interface GSMutableDictionary : NSObject // Help the compiler @end + +@interface GSXMLPListParser : NSObject +{ + NSXMLParser *theParser; + NSMutableString *value; + NSMutableArray *stack; + NSString *key; + BOOL inArray; + BOOL inDictionary; + id plist; + NSPropertyListMutabilityOptions opts; +} + +- (id) initWithData: (NSData*)data + mutability: (NSPropertyListMutabilityOptions)options; +- (BOOL) parse; +- (void) parser: (NSXMLParser *)parser + foundCharacters: (NSString *)string; +- (void) parser: (NSXMLParser *)parser + didStartElement: (NSString *)elementName + namespaceURI: (NSString *)namespaceURI + qualifiedName: (NSString *)qualifiedName + attributes: (NSDictionary *)attributeDict; +- (void) parser: (NSXMLParser *)parser + didEndElement: (NSString *)elementName + namespaceURI: (NSString *)namespaceURI + qualifiedName: (NSString *)qName; +- (id) result; +@end + +@implementation GSXMLPListParser + +- (void) dealloc +{ + RELEASE(key); + RELEASE(stack); + RELEASE(plist); + RELEASE(value); + RELEASE(theParser); + [super dealloc]; +} + +- (id) initWithData: (NSData*)data + mutability: (NSPropertyListMutabilityOptions)options +{ + if ((self = [super init]) != nil) + { + stack = [[NSMutableArray alloc] initWithCapacity: 10]; + theParser = [[NSXMLParser alloc] initWithData: data]; + [theParser setDelegate: self]; + opts = options; + } + return self; +} + +- (void) parser: (NSXMLParser *)parser + foundCharacters: (NSString *)string +{ + if (value == nil) + { + value = [[NSMutableString alloc] initWithCapacity: 50]; + } + [value appendString: string]; +} + +- (void) parser: (NSXMLParser *)parser + didStartElement: (NSString *)elementName + namespaceURI: (NSString *)namespaceURI + qualifiedName: (NSString *)qualifiedName + attributes: (NSDictionary *)attributeDict +{ + if ([elementName isEqualToString: @"dict"] == YES) + { + NSMutableDictionary *d; + + d = [[NSMutableDictionary alloc] initWithCapacity: 10]; + [stack addObject: d]; + RELEASE(d); + inDictionary = YES; + inArray = NO; + } + else if ([elementName isEqualToString: @"array"] == YES) + { + NSMutableArray *a; + + a = [[NSMutableArray alloc] initWithCapacity: 10]; + [stack addObject: a]; + RELEASE(a); + inArray = YES; + inDictionary = NO; + } +} + +- (void) parser: (NSXMLParser *)parser + didEndElement: (NSString *)elementName + namespaceURI: (NSString *)namespaceURI + qualifiedName: (NSString *)qName +{ + BOOL inContainer = NO; + + if ([elementName isEqualToString: @"dict"] == YES) + { + inContainer = YES; + } + if ([elementName isEqualToString: @"array"] == YES) + { + inContainer = YES; + } + + if (inContainer) + { + if (opts != NSPropertyListImmutable) + { + ASSIGN(plist, [stack lastObject]); + } + else + { + ASSIGN(plist, [[stack lastObject] makeImmutableCopyOnFail: NO]); + } + inArray = NO; + inDictionary = NO; + if ([stack count] > 0) + { + id last; + + [stack removeLastObject]; + last = [stack lastObject]; + if ([last isKindOfClass: [NSArray class]] == YES) + { + inArray = YES; + } + else if ([last isKindOfClass: [NSDictionary class]] == YES) + { + inDictionary = YES; + } + } + } + else if ([elementName isEqualToString: @"key"] == YES) + { + ASSIGN(key, [value makeImmutableCopyOnFail: NO]); + DESTROY(value); + return; + } + else if ([elementName isEqualToString: @"data"]) + { + NSData *d; + + d = [GSMimeDocument decodeBase64: + [value dataUsingEncoding: NSASCIIStringEncoding]]; + if (opts == NSPropertyListMutableContainersAndLeaves) + { + d = AUTORELEASE([d mutableCopy]); + } + ASSIGN(plist, d); + if (d == nil) + { + [parser abortParsing]; + return; + } + } + else if ([elementName isEqualToString: @"date"]) + { + id result; + + if ([value hasSuffix: @"Z"] == YES && [value length] == 20) + { + result = [NSCalendarDate dateWithString: value + calendarFormat: @"%Y-%m-%dT%H:%M:%SZ"]; + } + else + { + result = [NSCalendarDate dateWithString: value + calendarFormat: @"%Y-%m-%d %H:%M:%S %z"]; + } + ASSIGN(plist, result); + } + else if ([elementName isEqualToString: @"string"]) + { + id o; + + if (opts == NSPropertyListMutableContainersAndLeaves) + { + if (value == nil) + { + o = [NSMutableString string]; + } + else + { + o = value; + } + } + else + { + if (value == nil) + { + o = @""; + } + else + { + o = [value makeImmutableCopyOnFail: NO]; + } + } + ASSIGN(plist, o); + } + else if ([elementName isEqualToString: @"integer"]) + { + ASSIGN(plist, [NSNumber numberWithInt: [value intValue]]); + } + else if ([elementName isEqualToString: @"real"]) + { + ASSIGN(plist, [NSNumber numberWithDouble: [value doubleValue]]); + } + else if ([elementName isEqualToString: @"true"]) + { + ASSIGN(plist, [NSNumber numberWithBool: YES]); + } + else if ([elementName isEqualToString: @"false"]) + { + ASSIGN(plist, [NSNumber numberWithBool: NO]); + } + else if ([elementName isEqualToString: @"plist"]) + { + DESTROY(value); + return; + } + else // invalid tag + { + NSLog(@"unrecognized tag <%@>", elementName); + [parser abortParsing]; + return; + } + + if (inArray == YES) + { + [[stack lastObject] addObject: plist]; + } + else if (inDictionary == YES) + { + if (key == nil) + { + [parser abortParsing]; + return; + } + [(NSMutableDictionary*)[stack lastObject] setObject: plist forKey: key]; + DESTROY(key); + } + DESTROY(value); +} + +- (BOOL) parse +{ + return [theParser parse]; +} + +- (id) result +{ + return plist; +} + +@end + + + + @interface GSBinaryPLParser : NSObject { NSPropertyListMutabilityOptions mutability; @@ -83,13 +345,13 @@ extern BOOL GSScanDouble(unichar*, unsigned, double*); id root; // Number of bytes per object table index - unsigned int index_size; + unsigned int index_size; // Number of bytes per object table entry unsigned int offset_size; unsigned int table_start; - unsigned int table_size; - unsigned int *table; + unsigned int table_size; + unsigned int *table; } + (void) serializePropertyList: (id)aPropertyList intoData: (NSMutableData *)destination; @@ -1880,16 +2142,35 @@ OAppend(id obj, NSDictionary *loc, unsigned lev, unsigned step, [keyArray getObjects: keys]; } - for (i = 0; i < numKeys; i++) - { - if (GSObjCClass(keys[i]) == lastClass) - continue; - if ([keys[i] respondsToSelector: @selector(compare:)] == NO) + if (x == NSPropertyListXMLFormat_v1_0) + { + /* This format can only use strings as keys. + */ + lastClass = [NSString class]; + for (i = 0; i < numKeys; i++) { - canCompare = NO; - break; + if ([keys[i] isKindOfClass: lastClass] == NO) + { + [NSException raise: NSInvalidArgumentException + format: @"Bad key in property list: '%@'", keys[i]]; + } + } + } + else + { + /* All keys must respond to -compare: for sorting. + */ + for (i = 0; i < numKeys; i++) + { + if (GSObjCClass(keys[i]) == lastClass) + continue; + if ([keys[i] respondsToSelector: @selector(compare:)] == NO) + { + canCompare = NO; + break; + } + lastClass = GSObjCClass(keys[i]); } - lastClass = GSObjCClass(keys[i]); } if (canCompare == YES) @@ -2073,7 +2354,7 @@ static BOOL classInitialized = NO; { classInitialized = YES; -#ifdef HAVE_LIBXML +#if HAVE_LIBXML /* * Cache XML node information. */ @@ -2170,7 +2451,7 @@ GSPropertyListMake(id obj, NSDictionary *loc, BOOL xml, { style = NSPropertyListXMLFormat_v1_0; } - else if (GSUserDefaultsFlag(NSWriteOldStylePropertyLists)) + else if (GSPrivateDefaultsFlag(NSWriteOldStylePropertyLists) == YES) { style = NSPropertyListOpenStepFormat; } @@ -2219,10 +2500,10 @@ GSPropertyListMake(id obj, NSDictionary *loc, BOOL xml, case NSPropertyListXMLFormat_v1_0: return YES; - + case NSPropertyListBinaryFormat_v1_0: return YES; - + default: [NSException raise: NSInvalidArgumentException format: @"[%@ +%@]: unsupported format", @@ -2281,9 +2562,6 @@ GSPropertyListMake(id obj, NSDictionary *loc, BOOL xml, { // It begins with ' 0x11) && (c <= 0x13)) { - unsigned len = 1 << (c - 0x10); + unsigned len = c - 0x0f; unsigned char buffer[len]; int i; unsigned long num = 0; - + [data getBytes: &buffer range: NSMakeRange(*counter, len)]; *counter += len; for (i = 0; i < len; i++) @@ -2705,7 +3002,7 @@ GSPropertyListMake(id obj, NSDictionary *loc, BOOL xml, { result = [NSNumber numberWithUnsignedInt: (unsigned int)num]; } - else + else { result = [NSNumber numberWithUnsignedLongLong: num]; } @@ -3071,7 +3368,7 @@ GSPropertyListMake(id obj, NSDictionary *loc, BOOL xml, } table = objc_malloc(table_size * sizeof(int)); - + objectsToDoList = [[NSMutableArray alloc] init]; objectList = [[NSMutableArray alloc] init]; @@ -3108,7 +3405,7 @@ GSPropertyListMake(id obj, NSDictionary *loc, BOOL xml, - (void) markOffset: (unsigned int) offset for: (id)object { unsigned int oid; - + oid = [objectList indexOfObject: object]; if (oid == NSNotFound) { @@ -3131,10 +3428,10 @@ GSPropertyListMake(id obj, NSDictionary *loc, BOOL xml, unsigned int i; unsigned char *buffer; unsigned int last_offset; - + table_start = [dest length]; - // This is a bit too much, as the length - // of the last object is added. + // This is a bit too much, as the length + // of the last object is added. last_offset = table_start; if (last_offset < 256) @@ -3169,7 +3466,7 @@ GSPropertyListMake(id obj, NSDictionary *loc, BOOL xml, for (i = 0; i < len; i++) { unsigned char ci; - + ci = table[i]; buffer[i] = ci; } @@ -3179,7 +3476,7 @@ GSPropertyListMake(id obj, NSDictionary *loc, BOOL xml, for (i = 0; i < len; i++) { unsigned short si; - + si = table[i]; buffer[2 * i] = (si >> 8); buffer[2 * i + 1] = si % 256; @@ -3190,7 +3487,7 @@ GSPropertyListMake(id obj, NSDictionary *loc, BOOL xml, for (i = 0; i < len; i++) { unsigned int si; - + si = table[i]; buffer[3 * i] = (si >> 16); buffer[3 * i + 1] = (si >> 8) % 256; @@ -3202,7 +3499,7 @@ GSPropertyListMake(id obj, NSDictionary *loc, BOOL xml, for (i = 0; i < len; i++) { unsigned int si; - + si = table[i]; buffer[4 * i] = (si >> 24); buffer[4 * i + 1] = (si >> 16) % 256; @@ -3226,9 +3523,9 @@ GSPropertyListMake(id obj, NSDictionary *loc, BOOL xml, meta[i] = 0; } - meta[6] = offset_size; + meta[6] = offset_size; meta[7] = index_size; - + len = [objectList count]; meta[12] = (len >> 24); meta[13] = (len >> 16) % 256; @@ -3238,8 +3535,8 @@ GSPropertyListMake(id obj, NSDictionary *loc, BOOL xml, meta[29] = (table_start >> 16) % 256; meta[30] = (table_start >> 8) % 256; meta[31] = table_start % 256; - - [dest appendBytes: meta length: 32]; + + [dest appendBytes: meta length: 32]; } - (unsigned int) indexForObject: (id)object @@ -3264,14 +3561,14 @@ GSPropertyListMake(id obj, NSDictionary *loc, BOOL xml, unsigned char oid; oid = index; - [dest appendBytes: &oid length: 1]; + [dest appendBytes: &oid length: 1]; } else if (index_size == 2) { unsigned short oid; oid = NSSwapHostShortToBig(index); - [dest appendBytes: &oid length: 2]; + [dest appendBytes: &oid length: 2]; } else if (index_size == 4) { @@ -3298,7 +3595,7 @@ GSPropertyListMake(id obj, NSDictionary *loc, BOOL xml, code = 0x10; [dest appendBytes: &code length: 1]; c = count; - [dest appendBytes: &c length: 1]; + [dest appendBytes: &c length: 1]; } else if (count < 256 * 256) { @@ -3322,7 +3619,7 @@ GSPropertyListMake(id obj, NSDictionary *loc, BOOL xml, - (void) storeData: (NSData*) data { unsigned int len; - unsigned char code; + unsigned char code; len = [data length]; @@ -3345,12 +3642,12 @@ GSPropertyListMake(id obj, NSDictionary *loc, BOOL xml, { unsigned int len; BOOL ascii = YES; - unsigned char code; + unsigned char code; unsigned int i; unichar uchar; len = [string length]; - + for (i = 0; i < len; i++) { uchar = [string characterAtIndex: i]; @@ -3396,7 +3693,7 @@ GSPropertyListMake(id obj, NSDictionary *loc, BOOL xml, else { unichar *buffer; - + code = 0x6F; [dest appendBytes: &code length: 1]; buffer = objc_malloc(sizeof(unichar)*(len + 1)); @@ -3415,17 +3712,17 @@ GSPropertyListMake(id obj, NSDictionary *loc, BOOL xml, - (void) storeNumber: (NSNumber*) number { const char *type; - unsigned char code; + unsigned char code; type = [number objCType]; switch (*type) { - case 'c': - case 'C': - case 's': - case 'S': - case 'i': + case 'c': + case 'C': + case 's': + case 'S': + case 'i': case 'I': case 'l': case 'L': @@ -3454,7 +3751,7 @@ GSPropertyListMake(id obj, NSDictionary *loc, BOOL xml, code = 0x10; [dest appendBytes: &code length: 1]; cval = (unsigned char) val; - [dest appendBytes: &cval length: 1]; + [dest appendBytes: &cval length: 1]; } else if (val < 256 * 256) { @@ -3511,7 +3808,7 @@ GSPropertyListMake(id obj, NSDictionary *loc, BOOL xml, - (void) storeDate: (NSDate*) date { - unsigned char code; + unsigned char code; double out; code = 0x33; @@ -3522,7 +3819,7 @@ GSPropertyListMake(id obj, NSDictionary *loc, BOOL xml, - (void) storeArray: (NSArray*) array { - unsigned char code; + unsigned char code; unsigned int len; unsigned int i; @@ -3539,12 +3836,12 @@ GSPropertyListMake(id obj, NSDictionary *loc, BOOL xml, [dest appendBytes: &code length: 1]; [self storeCount: len]; } - + for (i = 0; i < len; i++) { id obj; unsigned int oid; - + obj = [array objectAtIndex: i]; oid = [self indexForObject: obj]; [self storeIndex: oid]; @@ -3553,7 +3850,7 @@ GSPropertyListMake(id obj, NSDictionary *loc, BOOL xml, - (void) storeDictionary: (NSDictionary*) dict { - unsigned char code; + unsigned char code; NSNumber *num; unsigned int i; @@ -3576,7 +3873,7 @@ GSPropertyListMake(id obj, NSDictionary *loc, BOOL xml, else { unsigned short si; - + code = 0x81; [dest appendBytes: &code length: 1]; si = NSSwapHostShortToBig((unsigned short)index); @@ -3595,7 +3892,7 @@ GSPropertyListMake(id obj, NSDictionary *loc, BOOL xml, key = [keys objectAtIndex: i]; [objects addObject: [dict objectForKey: key]]; } - + if (len < 0x0F) { code = 0xD0 + len; @@ -3607,22 +3904,22 @@ GSPropertyListMake(id obj, NSDictionary *loc, BOOL xml, [dest appendBytes: &code length: 1]; [self storeCount: len]; } - + for (i = 0; i < len; i++) { id obj; unsigned int oid; - + obj = [keys objectAtIndex: i]; oid = [self indexForObject: obj]; [self storeIndex: oid]; } - + for (i = 0; i < len; i++) { id obj; unsigned int oid; - + obj = [objects objectAtIndex: i]; oid = [self indexForObject: obj]; [self storeIndex: oid]; @@ -3658,7 +3955,7 @@ GSPropertyListMake(id obj, NSDictionary *loc, BOOL xml, { [self storeDictionary: object]; } - else + else { NSLog(@"Unknown object class %@", object); } @@ -3679,7 +3976,7 @@ GSPropertyListMake(id obj, NSDictionary *loc, BOOL xml, done = YES; } NS_HANDLER - { + { [self cleanup]; index_size += 1; } diff --git a/Source/NSProtocolChecker.m b/Source/NSProtocolChecker.m index 641c26911..64a39c011 100644 --- a/Source/NSProtocolChecker.m +++ b/Source/NSProtocolChecker.m @@ -20,7 +20,8 @@ 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., 51 Franklin Street, Fifth Floor, Boston, MA 02111 USA. + Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02111 USA. NSProtocolChecker class reference $Date$ $Revision$ diff --git a/Source/NSProxy.m b/Source/NSProxy.m index 1a56166d8..872feb1e9 100644 --- a/Source/NSProxy.m +++ b/Source/NSProxy.m @@ -18,7 +18,8 @@ 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., 51 Franklin Street, Fifth Floor, Boston, MA 02111 USA. + Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02111 USA. NSProxy class reference $Date$ $Revision$ diff --git a/Source/NSRange.m b/Source/NSRange.m index 0957dc488..390b42aa9 100644 --- a/Source/NSRange.m +++ b/Source/NSRange.m @@ -18,7 +18,8 @@ * * 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., 51 Franklin Street, Fifth Floor, Boston, MA 02111 USA. + * Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02111 USA. NSRange class reference $Date$ $Revision$ diff --git a/Source/NSRunLoop.m b/Source/NSRunLoop.m index 5e7af174f..8ececc78e 100644 --- a/Source/NSRunLoop.m +++ b/Source/NSRunLoop.m @@ -37,6 +37,7 @@ #include "Foundation/NSAutoreleasePool.h" #include "Foundation/NSPort.h" #include "Foundation/NSTimer.h" +#include "Foundation/NSNotification.h" #include "Foundation/NSNotificationQueue.h" #include "Foundation/NSRunLoop.h" #include "Foundation/NSStream.h" @@ -45,6 +46,7 @@ #include "GSRunLoopCtxt.h" #include "GSRunLoopWatcher.h" #include "GSStream.h" + #include "GSPrivate.h" #ifdef HAVE_SYS_TYPES_H @@ -68,8 +70,6 @@ NSString * const NSDefaultRunLoopMode = @"NSDefaultRunLoopMode"; static NSDate *theFuture = nil; -extern BOOL GSCheckTasks(); - @interface NSObject (OptionalPortRunLoop) - (void) getFds: (int*)fds count: (int*)count; @end @@ -99,6 +99,13 @@ extern BOOL GSCheckTasks(); @implementation GSRunLoopPerformer +- (void) dealloc +{ + RELEASE(target); + RELEASE(argument); + [super dealloc]; +} + - (void) fire { [target performSelector: selector withObject: argument]; @@ -113,8 +120,8 @@ extern BOOL GSCheckTasks(); if (self) { selector = aSelector; - target = aTarget; - argument = anArgument; + target = RETAIN(aTarget); + argument = RETAIN(anArgument); order = theOrder; } return self; @@ -632,11 +639,6 @@ static NSComparisonResult tSort(GSIArrayItem i0, GSIArrayItem i1) @end -extern SEL wRelSel; -extern SEL wRetSel; -extern IMP wRelImp; -extern IMP wRetImp; - /** *

NSRunLoop instances handle various utility tasks that must * be performed repetitively in an application, such as processing input @@ -662,12 +664,6 @@ extern IMP wRetImp; { [self currentRunLoop]; theFuture = RETAIN([NSDate distantFuture]); -#if GS_WITH_GC == 0 - wRelSel = @selector(release); - wRetSel = @selector(retain); - wRelImp = [[GSRunLoopWatcher class] instanceMethodForSelector: wRelSel]; - wRetImp = [[GSRunLoopWatcher class] instanceMethodForSelector: wRetSel]; -#endif } } @@ -834,7 +830,7 @@ extern IMP wRetImp; { RELEASE(min_timer); } - GSNotifyASAP(); /* Post notifications. */ + GSPrivateNotifyASAP(); /* Post notifications. */ IF_NO_GC([arp emptyPool]); } _currentMode = savedMode; @@ -926,19 +922,19 @@ extern IMP wRetImp; || (i = GSIArrayCount(watchers)) == 0)) { NSDebugMLLog(@"NSRunLoop", @"no inputs in mode %@", mode); - GSNotifyASAP(); - GSNotifyIdle(); + GSPrivateNotifyASAP(); + GSPrivateNotifyIdle(); /* * Pause for as long as possible (up to the limit date) */ [NSThread sleepUntilDate: limit_date]; ti = [limit_date timeIntervalSinceNow]; - GSCheckTasks(); + GSPrivateCheckTasks(); if (context != nil) { [self _checkPerformers: context]; } - GSNotifyASAP(); + GSPrivateNotifyASAP(); _currentMode = savedMode; RELEASE(arp); NS_VOIDRETURN; @@ -972,10 +968,10 @@ extern IMP wRetImp; } if ([context pollUntil: timeout_ms within: _contextStack] == NO) { - GSNotifyIdle(); + GSPrivateNotifyIdle(); } [self _checkPerformers: context]; - GSNotifyASAP(); + GSPrivateNotifyASAP(); _currentMode = savedMode; /* * Once a poll has been completed on a context, we can remove that @@ -1022,9 +1018,9 @@ extern IMP wRetImp; /* * Notify if any tasks have completed. */ - if (GSCheckTasks() == YES) + if (GSPrivateCheckTasks() == YES) { - GSNotifyASAP(); + GSPrivateNotifyASAP(); } RELEASE(arp); return NO; @@ -1187,7 +1183,7 @@ extern IMP wRetImp; * Sets up sending of aSelector to target with argument.
* The selector is sent before the next runloop iteration (unless * cancelled before then) in any of the specified modes.
- * The target and argument objects are not retained.
+ * The target and argument objects are retained.
* The order value is used to determine the order in which messages * are sent if multiple messages have been set up. Messages with a lower * order value are sent first.
diff --git a/Source/NSScanner.m b/Source/NSScanner.m index a4f897221..b9d50eb94 100644 --- a/Source/NSScanner.m +++ b/Source/NSScanner.m @@ -140,8 +140,8 @@ typedef struct { GSPlaceholderStringClass = [GSPlaceholderString class]; NSConstantStringClass = [NSString constantStringClass]; _holder = (id)NSAllocateObject(GSPlaceholderStringClass, 0, 0); - externalEncoding = GetDefEncoding(); - if (GSIsByteEncoding(externalEncoding) == YES) + externalEncoding = [NSString defaultCStringEncoding]; + if (GSPrivateIsByteEncoding(externalEncoding) == YES) { internalEncoding = externalEncoding; } @@ -169,7 +169,10 @@ typedef struct { if (scanner != nil) { - [scanner setLocale: GSUserDefaultsDictionaryRepresentation()]; + NSDictionary *loc; + + loc = [[NSUserDefaults standardUserDefaults] dictionaryRepresentation]; + [scanner setLocale: loc]; } return scanner; } diff --git a/Source/NSSerializer.m b/Source/NSSerializer.m index 0a334d9af..c6412cbfe 100644 --- a/Source/NSSerializer.m +++ b/Source/NSSerializer.m @@ -18,8 +18,8 @@ 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., 51 Franklin Street, Fifth Floor, Boston, - MA 02111 USA. + Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02111 USA. NSSerializer class reference $Date$ $Revision$ @@ -36,6 +36,7 @@ #include "Foundation/NSLock.h" #include "Foundation/NSSet.h" #include "Foundation/NSThread.h" +#include "Foundation/NSNotification.h" #include "Foundation/NSNotificationQueue.h" #include "Foundation/NSObjCRuntime.h" #include "Foundation/NSValue.h" @@ -49,10 +50,6 @@ @class NSDataMalloc; @interface NSDataMalloc : NSObject // Help the compiler @end -@class GSInlineArray; -@class GSMutableArray; -@interface GSMutableArray : NSObject // Help the compiler -@end /* * Setup for inline operation of string map tables. diff --git a/Source/NSSocketPort.m b/Source/NSSocketPort.m index 98ab968c8..b78c05638 100644 --- a/Source/NSSocketPort.m +++ b/Source/NSSocketPort.m @@ -18,7 +18,8 @@ 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., 51 Franklin Street, Fifth Floor, Boston, MA 02111 USA. + Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02111 USA. */ #include "config.h" @@ -268,7 +269,7 @@ decodePort(NSData *data, NSString *defaultAddress) pi->addr, pnum); return nil; } - addr = [NSString stringWithCString: pi->addr]; + addr = [NSString stringWithUTF8String: pi->addr]; NSDebugFLLog(@"NSPort", @"Decoded port as '%@:%d'", addr, pnum); @@ -389,8 +390,8 @@ static Class runLoopClass; dummy = 1; if (ioctlsocket(d, FIONBIO, &dummy) == SOCKET_ERROR) { - NSLog(@"unable to set non-blocking mode on %d - %s", - d, GSLastErrorStr(errno)); + NSLog(@"unable to set non-blocking mode on %d - %@", + d, [NSError _last]); return nil; } #else /* !__MINGW32__ */ @@ -399,15 +400,15 @@ static Class runLoopClass; e |= NBLK_OPT; if (fcntl(d, F_SETFL, e) < 0) { - NSLog(@"unable to set non-blocking mode on %d - %s", - d, GSLastErrorStr(errno)); + NSLog(@"unable to set non-blocking mode on %d - %@", + d, [NSError _last]); return nil; } } else { - NSLog(@"unable to get non-blocking mode on %d - %s", - d, GSLastErrorStr(errno)); + NSLog(@"unable to get non-blocking mode on %d - %@", + d, [NSError _last]); return nil; } #endif @@ -544,9 +545,9 @@ static Class runLoopClass; if (errno != EINPROGRESS) #endif { - NSLog(@"unable to make connection to %s:%d - %s", + NSLog(@"unable to make connection to %s:%d - %@", inet_ntoa(sockAddr.sin_addr), - GSSwapBigI16ToHost(sockAddr.sin_port), GSLastErrorStr(errno)); + GSSwapBigI16ToHost(sockAddr.sin_port), [NSError _last]); if (addrNum < [addrs count]) { BOOL result; @@ -816,7 +817,7 @@ static Class runLoopClass; #endif /* !__MINGW32__ */ { NSDebugMLLog(@"GSTcpHandle", - @"read failed - %s on 0x%x", GSLastErrorStr(errno), self); + @"read failed - %@ on 0x%p", [NSError _last], self); [self invalidate]; return; } @@ -1103,11 +1104,15 @@ static Class runLoopClass; int res = 0; unsigned len = sizeof(res); - if (getsockopt(desc, SOL_SOCKET, SO_ERROR, (char*)&res, &len) == 0 - && res != 0) + if (getsockopt(desc, SOL_SOCKET, SO_ERROR, (char*)&res, &len) != 0) { state = GS_H_UNCON; - NSLog(@"connect attempt failed - %s", GSLastErrorStr(res)); + NSLog(@"connect attempt failed - %@", [NSError _last]); + } + else if (res != 0) + { + state = GS_H_UNCON; + NSLog(@"connect attempt failed - %@", [NSError _systemError: res]); } else { @@ -1117,7 +1122,7 @@ static Class runLoopClass; if (len == (int)[d length]) { RELEASE(defaultAddress); - defaultAddress = RETAIN([NSString stringWithCString: + defaultAddress = RETAIN([NSString stringWithUTF8String: inet_ntoa(sockAddr.sin_addr)]); NSDebugMLLog(@"GSTcpHandle", @"wrote %d bytes on 0x%x", len, self); @@ -1126,8 +1131,8 @@ static Class runLoopClass; else { state = GS_H_UNCON; - NSLog(@"connect write attempt failed - %s", - GSLastErrorStr(errno)); + NSLog(@"connect write attempt failed - %@", + [NSError _last]); } RELEASE(d); } @@ -1165,7 +1170,7 @@ static Class runLoopClass; if (errno != EINTR && errno != EAGAIN) #endif /* !__MINGW32__ */ { - NSLog(@"write attempt failed - %s", GSLastErrorStr(errno)); + NSLog(@"write attempt failed - %@", [NSError _last]); [self invalidate]; return; } @@ -1261,7 +1266,7 @@ static Class runLoopClass; if (ocurredEvents.lNetworkEvents & FD_CONNECT) { [self receivedEventWrite]; - GSNotifyASAP(); + GSPrivateNotifyASAP(); if (desc == INVALID_SOCKET) { M_UNLOCK(myLock); @@ -1272,7 +1277,7 @@ static Class runLoopClass; if (ocurredEvents.lNetworkEvents & FD_READ) { [self receivedEventRead]; - GSNotifyASAP(); + GSPrivateNotifyASAP(); if (desc == INVALID_SOCKET) { M_UNLOCK(myLock); @@ -1283,7 +1288,7 @@ static Class runLoopClass; if (ocurredEvents.lNetworkEvents & FD_OOB) { [self receivedEventRead]; - GSNotifyASAP(); + GSPrivateNotifyASAP(); if (desc == INVALID_SOCKET) { M_UNLOCK(myLock); @@ -1295,7 +1300,7 @@ static Class runLoopClass; { readyToSend = YES; [self receivedEventWrite]; - GSNotifyASAP(); + GSPrivateNotifyASAP(); if (desc == INVALID_SOCKET) { M_UNLOCK(myLock); @@ -1306,7 +1311,7 @@ static Class runLoopClass; if (ocurredEvents.lNetworkEvents & FD_CLOSE) { [self receivedEventRead]; - GSNotifyASAP(); + GSPrivateNotifyASAP(); if (desc == INVALID_SOCKET) { M_UNLOCK(myLock); @@ -1634,7 +1639,7 @@ static Class tcpPortClass; else if ((desc = socket(AF_INET, SOCK_STREAM, PF_UNSPEC)) == INVALID_SOCKET) { - NSLog(@"unable to create socket - %s", GSLastErrorStr(errno)); + NSLog(@"unable to create socket - %@", [NSError _last]); DESTROY(port); } #ifndef BROKEN_SO_REUSEADDR @@ -1648,29 +1653,29 @@ static Class tcpPortClass; sizeof(reuse)) < 0) { (void) close(desc); - NSLog(@"unable to set reuse on socket - %s", - GSLastErrorStr(errno)); + NSLog(@"unable to set reuse on socket - %@", + [NSError _last]); DESTROY(port); } #endif else if (bind(desc, (struct sockaddr *)&sockaddr, sizeof(sockaddr)) == SOCKET_ERROR) { - NSLog(@"unable to bind to port %s:%d - %s", - inet_ntoa(sockaddr.sin_addr), number, GSLastErrorStr(errno)); + NSLog(@"unable to bind to port %s:%d - %@", + inet_ntoa(sockaddr.sin_addr), number, [NSError _last]); (void) close(desc); DESTROY(port); } else if (listen(desc, 128) == SOCKET_ERROR) { - NSLog(@"unable to listen on port - %s", GSLastErrorStr(errno)); + NSLog(@"unable to listen on port - %@", [NSError _last]); (void) close(desc); DESTROY(port); } else if (getsockname(desc, (struct sockaddr*)&sockaddr, &i) == SOCKET_ERROR) { - NSLog(@"unable to get socket name - %s", GSLastErrorStr(errno)); + NSLog(@"unable to get socket name - %@", [NSError _last]); (void) close(desc); DESTROY(port); } @@ -1693,7 +1698,8 @@ static Class tcpPortClass; NSLog(@"Invalid Event - '%d'", WSAGetLastError()); abort(); } - rc = WSAEventSelect(port->listener, port->eventListener, FD_ACCEPT); + rc = WSAEventSelect(port->listener, + port->eventListener, FD_ACCEPT); NSAssert(rc == 0, @"WSAEventSelect failed!"); #endif /* @@ -1725,7 +1731,8 @@ static Class tcpPortClass; * Make sure we have the map table for this port. */ port->portNum = number; - thePorts = (NSMapTable*)NSMapGet(tcpPortMap, (void*)(uintptr_t)number); + thePorts + = (NSMapTable*)NSMapGet(tcpPortMap, (void*)(uintptr_t)number); if (thePorts == 0) { /* @@ -1734,7 +1741,8 @@ static Class tcpPortClass; */ thePorts = NSCreateMapTable(NSIntMapKeyCallBacks, NSNonOwnedPointerMapValueCallBacks, 0); - NSMapInsert(tcpPortMap, (void*)(uintptr_t)number, (void*)thePorts); + NSMapInsert(tcpPortMap, + (void*)(uintptr_t)number, (void*)thePorts); } /* * Record the port by host. @@ -1967,7 +1975,7 @@ static Class tcpPortClass; handle = nil; if ((sock = socket(AF_INET, SOCK_STREAM, PF_UNSPEC)) == INVALID_SOCKET) { - NSLog(@"unable to create socket - %s", GSLastErrorStr(errno)); + NSLog(@"unable to create socket - %@", [NSError _last]); } #ifndef BROKEN_SO_REUSEADDR /* @@ -1980,13 +1988,13 @@ static Class tcpPortClass; sizeof(opt)) < 0) { (void)close(sock); - NSLog(@"unable to set reuse on socket - %s", GSLastErrorStr(errno)); + NSLog(@"unable to set reuse on socket - %@", [NSError _last]); } #endif else if ((handle = [GSTcpHandle handleWithDescriptor: sock]) == nil) { (void)close(sock); - NSLog(@"unable to create GSTcpHandle - %s", GSLastErrorStr(errno)); + NSLog(@"unable to create GSTcpHandle - %@", [NSError _last]); } else { @@ -2057,19 +2065,20 @@ static Class tcpPortClass; thePorts = NSMapGet(tcpPortMap, (void*)(uintptr_t)portNum); if (thePorts != 0) { - if (listener >= 0) - { - (void) close(listener); - listener = -1; -#if defined(__MINGW32__) - WSACloseEvent(eventListener); - eventListener = WSA_INVALID_EVENT; -#endif - } NSMapRemove(thePorts, (void*)host); } M_UNLOCK(tcpPortLock); + if (listener >= 0) + { + (void) close(listener); + listener = -1; +#if defined(__MINGW32__) + WSACloseEvent(eventListener); + eventListener = WSA_INVALID_EVENT; +#endif + } + if (handles != 0) { handleArray = NSAllMapTableValues(handles); @@ -2174,7 +2183,7 @@ static Class tcpPortClass; */ handle = [GSTcpHandle handleWithDescriptor: desc]; memcpy(&handle->sockAddr, &sockAddr, sizeof(sockAddr)); - handle->defaultAddress = RETAIN([NSString stringWithCString: + handle->defaultAddress = RETAIN([NSString stringWithUTF8String: inet_ntoa(sockAddr.sin_addr)]); [handle setState: GS_H_ACCEPT]; @@ -2216,6 +2225,28 @@ static Class tcpPortClass; } } +- (void) release +{ + M_LOCK(tcpPortLock); + if (NSDecrementExtraRefCountWasZero(self)) + { + NSMapTable *thePorts; + + thePorts = NSMapGet(tcpPortMap, (void*)(uintptr_t)portNum); + if (thePorts != 0) + { + NSMapRemove(thePorts, host); + } + M_UNLOCK(tcpPortLock); + [self dealloc]; + } + else + { + M_UNLOCK(tcpPortLock); + } +} + + /* * This is called when a tcp/ip socket connection is broken. We remove the * connection handle from this port and, if this was the last handle to a diff --git a/Source/NSSocketPortNameServer.m b/Source/NSSocketPortNameServer.m index db9b8d78e..182f432d3 100644 --- a/Source/NSSocketPortNameServer.m +++ b/Source/NSSocketPortNameServer.m @@ -18,20 +18,22 @@ 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., 51 Franklin Street, Fifth Floor, Boston, - MA 02111 USA. + Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02111 USA. $Date$ $Revision$ */ #include "config.h" #include "Foundation/NSString.h" +#include "Foundation/NSData.h" #include "Foundation/NSByteOrder.h" #include "Foundation/NSException.h" #include "Foundation/NSAutoreleasePool.h" #include "Foundation/NSLock.h" #include "Foundation/NSFileHandle.h" #include "Foundation/NSRunLoop.h" +#include "Foundation/NSNotification.h" #include "Foundation/NSNotificationQueue.h" #include "Foundation/NSPort.h" #include "Foundation/NSMapTable.h" @@ -554,7 +556,7 @@ typedef enum { serverLock = [NSRecursiveLock new]; modes = [[NSArray alloc] initWithObjects: &mode count: 1]; #ifdef GDOMAP_PORT_OVERRIDE - serverPort = RETAIN([NSString stringWithCString: + serverPort = RETAIN([NSString stringWithUTF8String: make_gdomap_port(GDOMAP_PORT_OVERRIDE)]); #endif portClass = [NSSocketPort class]; @@ -738,7 +740,7 @@ typedef enum { [array addObject: com]; RELEASE(com); [com setAddr: svrs[count]]; - addr = [NSString stringWithCString: + addr = [NSString stringWithUTF8String: (char*)inet_ntoa(svrs[count])]; [com startPortLookup: name onHost: addr]; count++; @@ -802,7 +804,7 @@ typedef enum { if (*port) { - *addr = [NSString stringWithCString: inet_ntoa(singleServer)]; + *addr = [NSString stringWithUTF8String: inet_ntoa(singleServer)]; return YES; } else diff --git a/Source/NSSortDescriptor.m b/Source/NSSortDescriptor.m index f856cbacb..ebd0546ac 100644 --- a/Source/NSSortDescriptor.m +++ b/Source/NSSortDescriptor.m @@ -79,31 +79,6 @@ [super dealloc]; } -/* Hash function to hash up to limit bytes from data of specified length. - * If the flag is NO then a result of 0 is mapped to 0xffffffff. - * This is a pretty useful general purpose hash function. - */ -static inline unsigned -GSPrivateHash(const void *data, unsigned length, unsigned limit, BOOL zero) -{ - unsigned ret = length; - unsigned l = length; - - if (limit < length) - { - l = limit; - } - while (l-- > 0) - { - ret = (ret << 5) + ret + ((const unsigned char*)data)[l]; - } - if (ret == 0 && zero == NO) - { - ret = 0xffffffff; - } - return ret; -} - - (unsigned) hash { const char *sel = GSNameFromSelector(_selector); @@ -273,7 +248,7 @@ SortObjectsWithDescriptor(id *objects, - (NSArray *) sortedArrayUsingDescriptors: (NSArray *) sortDescriptors { - NSMutableArray *sortedArray = [NSMutableArray arrayWithArray: self]; + NSMutableArray *sortedArray = [GSMutableArray arrayWithArray: self]; [sortedArray sortUsingDescriptors: sortDescriptors]; @@ -348,3 +323,21 @@ SortRange(id *objects, NSRange range, id *descriptors, @end +@implementation GSMutableArray (NSSortDescriptorSorting) + +- (void) sortUsingDescriptors: (NSArray *)sortDescriptors +{ + unsigned dCount = [sortDescriptors count]; + + if (_count > 1 && dCount > 0) + { + GS_BEGINIDBUF(descriptors, dCount); + + [sortDescriptors getObjects: descriptors]; + SortRange(_contents_array, NSMakeRange(0, _count), descriptors, dCount); + + GS_ENDIDBUF(); + } +} + +@end diff --git a/Source/NSSpellServer.m b/Source/NSSpellServer.m new file mode 100644 index 000000000..1ffd258f6 --- /dev/null +++ b/Source/NSSpellServer.m @@ -0,0 +1,471 @@ +/** NSSpellServer + + Class to allow a spell checker to be available to other apps. + + Copyright (C) 2001, 1996 Free Software Foundation, Inc. + + Author by: Gregory John Casamento + Date: 2001 + Author: Scott Christley + Date: 1996 + + 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; see the file COPYING.LIB. + If not, write to the Free Software Foundation, + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +*/ + +#include "config.h" +#include "Foundation/NSSpellServer.h" +#include "Foundation/NSDictionary.h" +#include "Foundation/NSRunLoop.h" +#include "Foundation/NSFileManager.h" +#include "Foundation/NSUserDefaults.h" +#include "Foundation/NSPathUtilities.h" +#include "Foundation/NSConnection.h" +#include "Foundation/NSProcessInfo.h" +#include "Foundation/NSString.h" +#include "Foundation/NSException.h" +#include "Foundation/NSSet.h" + +/* User dictionary location */ +static NSString *GNU_UserDictionariesDir = @"Dictionaries"; + +// Function to create name for spell server.... +NSString* +GSSpellServerName(NSString *vendor, NSString *language) +{ + NSString *serverName = nil; + + if (language == nil || vendor == nil) + { + return nil; + } + + serverName = [[vendor stringByAppendingString: language] + stringByAppendingString: @"SpellChecker"]; + + return serverName; +} + +@implementation NSSpellServer + +// Class methods ++ (void) initialize +{ + if (self == [NSSpellServer class]) + { + // Initial version + [self setVersion: 1]; + } +} + +// Non-private Instance methods +- (id) init +{ + NSArray *userLanguages = [NSUserDefaults userLanguages]; + NSString *currentLanguage = [userLanguages objectAtIndex: 0]; + + if ((self = [super init]) != nil) + { + _delegate = nil; + _ignoredWords = nil; + ASSIGN(_userDictionaries, [NSMutableDictionary dictionary]); + ASSIGN(_currentLanguage, currentLanguage); + } + + return self; +} + +// Cleanup when deallocated +- (void) dealloc +{ + RELEASE(_userDictionaries); + RELEASE(_currentLanguage); + [super dealloc]; +} + +// Checking in Your Service + +/** + * This method vends the spell server to the Distributed Objects system + * so that it can be connected to by clients. + */ +- (BOOL) registerLanguage: (NSString *)language + byVendor: (NSString *)vendor +{ + NSString *serverName = GSSpellServerName(vendor, language); + NSConnection *connection = nil; + BOOL result = NO; + + if (serverName == nil) + { + return NO; + } + + connection = [[NSConnection alloc] init]; + if (connection) + { + RETAIN(connection); + [connection setRootObject: self]; + result = [connection registerName: serverName]; + } + + return result; +} + +// Assigning a Delegate + +/** + * Return the spell server delegate. + */ +- (id) delegate +{ + return _delegate; +} + +/** + * This method is used to set the delegate of the spellserver. + * When a spelling service is run the spell server is vended out + * to DO. The spelling service must instantiate an instance of + * this class and set itself to be the delegate. This allows + * the service to respond to messages sent by the client. + */ +- (void) setDelegate: (id)anObject +{ + /* FIXME - we should not retain the delegate ! */ + RETAIN(anObject); + ASSIGN(_delegate, anObject); +} + +// Running the Service +/** + * Initiate the run loop of this service. Once the spell server + * object is vended, this method is called so that the server can + * start responding to the messages sent by the client. These + * messages are passed on to the NSSpellServer instance's delegate. + */ +- (void) run +{ + // Start the runloop explicitly. + [[NSRunLoop currentRunLoop] run]; +} + +// Private method +// Determine the path to the dictionary +/** + * Path to the dictionary for the specified language. + */ +- (NSString *) _pathToDictionary: (NSString *)currentLanguage +{ + NSString *path = nil; + NSString *user_gsroot = nil; + + user_gsroot = [NSSearchPathForDirectoriesInDomains(NSLibraryDirectory, + NSUserDomainMask, YES) lastObject]; + + if (currentLanguage != nil) + { + NSString *dirPath = nil; + NSFileManager *mgr = [NSFileManager defaultManager]; + + // Build the path and try to get the dictionary + dirPath = [user_gsroot stringByAppendingPathComponent: + GNU_UserDictionariesDir]; + path = [dirPath stringByAppendingPathComponent: currentLanguage]; + + if (![mgr fileExistsAtPath: path ]) + { + if ([mgr fileExistsAtPath: dirPath]) + { + // The directory exists create the file. + NSArray *emptyDict = [NSArray array]; + + if (![emptyDict writeToFile: path atomically: YES]) + { + NSLog(@"Failed to create %@",path); + path = nil; + } + } + else + { + // The directory does not exist create it. + if ([mgr createDirectoryAtPath: dirPath attributes: nil]) + { + // Directory created. Now create the empty file. + NSArray *emptyDict = [NSArray array]; + + if (![emptyDict writeToFile: path atomically: YES]) + { + NSLog(@"Failed to create %@",path); + path = nil; + } + } + else + { + NSLog(@"Failed to create %@",dirPath); + path = nil; + } + } + } + } + + return path; +} + +// Private method +/** Open up dictionary stored in the user's directory. */ +- (NSMutableSet *) _openUserDictionary: (NSString *)language +{ + NSString *path = nil; + NSMutableSet *words = nil; + + if ((words = [_userDictionaries objectForKey: language]) == nil) + { + if ((path = [self _pathToDictionary: language]) != nil) + { + NSArray *wordarray = [NSArray arrayWithContentsOfFile: path]; + + if (wordarray == nil) + { + NSLog(@"Unable to load user dictionary from path %@",path); + } + else + { + words = [NSMutableSet setWithArray: wordarray]; + [_userDictionaries setObject: words forKey: language]; + } + } + else + { + NSLog(@"Unable to find user dictionary at: %@", path); + } + } + + // successful in opening the desired dictionary.. + return words; +} + +// Checking User Dictionaries +/** Check if word is in dict, flag determines if the search is case sensitive. */ +- (BOOL) _isWord: (NSString *)word + inDictionary: (NSSet *)dict + caseSensitive: (BOOL)flag +{ + BOOL result = NO; + NSString *dictWord = nil; + NSEnumerator *setEnumerator = nil; + + // Catch the odd cases before they start trouble later on... + if (word == nil || dict == nil) + { + return NO; // avoid checking, if NIL. + } + + if ([word length] == 0 || [dict count] == 0) + { + return NO; // avoid checking, if has no length. + } + + // Check the dictionary for the word... + setEnumerator = [dict objectEnumerator]; + while ((dictWord = [setEnumerator nextObject]) && result == NO) + { + // If the case is important then uppercase both strings + // and compare, otherwise do the comparison. + if (flag == NO) + { + NSString *upperWord = [word uppercaseString]; + NSString *upperDictWord = [dictWord uppercaseString]; + + result = [upperWord isEqualToString: upperDictWord]; + } + else + { + result = [word isEqualToString: dictWord]; + } + } + + if (result == NO && _ignoredWords) + { + NSEnumerator *arrayEnumerator = [_ignoredWords objectEnumerator]; + NSString *iword = nil; + + while ((iword = [arrayEnumerator nextObject]) && result == NO) + { + // If the case is important then uppercase both strings + // and compare, otherwise do the comparison. + if (flag == NO) + { + NSString *upperWord = [word uppercaseString]; + NSString *upperIWord = [iword uppercaseString]; + + result = [upperWord isEqualToString: upperIWord]; + } + else + { + result = [word isEqualToString: iword]; + } + } + } + + return result; +} + +// Checking User Dictionaries +/** +Checks to see if the word is in the user's dictionary. The user dictionary +is a set of words learned by the spell service for that particular user. +*/ +- (BOOL) isWordInUserDictionaries: (NSString *)word + caseSensitive: (BOOL)flag +{ + NSSet *userDict = [self _openUserDictionary: _currentLanguage]; + BOOL result = NO; + + if (userDict) + { + result = [self _isWord: word + inDictionary: userDict + caseSensitive: flag]; + } + + return result; +} + +/** Save the dictionary stored in user's directory. */ +- (BOOL) _saveUserDictionary: (NSString *)language +{ + NSString *path = nil; + + if ((path = [self _pathToDictionary: language]) != nil) + { + NSMutableSet *set = [_userDictionaries objectForKey: language]; + + if (![[set allObjects] writeToFile: path atomically: YES]) + { + NSLog(@"Unable to save dictionary to path %@",path); + return NO; + } + } + else + { + NSLog(@"Unable to save dictionary at: %@", path); + return NO; + } + // successful in saving the desired dictionary.. + return YES; +} + +/** Learn a new word and put it into the dictionary. */ +- (BOOL) _learnWord: (NSString *)word + inDictionary: (NSString *)language +{ + NSMutableSet *set = [self _openUserDictionary: language]; + [set addObject: word]; + + NS_DURING + { + [_delegate spellServer: self + didLearnWord: word + inLanguage: language]; + } + NS_HANDLER + { + NSLog(@"Call to delegate cause the following exception: %@", + [localException reason]); + } + NS_ENDHANDLER + + return [self _saveUserDictionary: language]; +} + +/** Forget a word and remove it from the dictionary. */ +- (BOOL)_forgetWord: (NSString *)word + inDictionary: (NSString *)language +{ + NSMutableSet *set = [self _openUserDictionary: language]; + [set removeObject: word]; + + NS_DURING + { + [_delegate spellServer: self + didForgetWord: word + inLanguage: language]; + } + NS_HANDLER + { + NSLog(@"Call to delegate caused following exception: %@", + [localException reason]); + } + NS_ENDHANDLER + + return [self _saveUserDictionary: language]; +} + +/** Find a misspelled word. */ +- (NSRange) _findMisspelledWordInString: (NSString *)stringToCheck + language: (NSString *)language + ignoredWords: (NSArray *)ignoredWords + wordCount: (int *)wordCount + countOnly: (BOOL)countOnly +{ + NSRange r = NSMakeRange(0,0); + + // Forward to delegate + NS_DURING + { + ASSIGN(_ignoredWords,ignoredWords); + r = [_delegate spellServer: self + findMisspelledWordInString: stringToCheck + language: language + wordCount: wordCount + countOnly: countOnly]; + _ignoredWords = nil; + } + NS_HANDLER + { + NSLog(@"Call to delegate caused the following exception: %@", + [localException reason]); + } + NS_ENDHANDLER + + return r; +} + +/** Suggest a correction for the word. */ +- (NSArray *) _suggestGuessesForWord: (NSString *)word + inLanguage: (NSString *)language +{ + NSArray *words = nil; + + // Forward to delegate + NS_DURING + { + words = [_delegate spellServer: self + suggestGuessesForWord: word + inLanguage: language]; + } + NS_HANDLER + { + NSLog(@"Call to delegate caused the following exception: %@", + [localException reason]); + } + NS_ENDHANDLER + + return words; +} + +@end diff --git a/Source/NSString.m b/Source/NSString.m index 48bb66b17..6317227cf 100644 --- a/Source/NSString.m +++ b/Source/NSString.m @@ -70,13 +70,13 @@ #include "Foundation/NSURL.h" #include "Foundation/NSMapTable.h" #include "Foundation/NSLock.h" +#include "Foundation/NSNotification.h" #include "Foundation/NSUserDefaults.h" #include "Foundation/NSDebug.h" // For private method _decodePropertyListForKey: #include "Foundation/NSKeyedArchiver.h" #include "GNUstepBase/GSMime.h" #include "GSPrivate.h" -#include "GSFormat.h" #include #include #ifdef HAVE_UNISTD_H @@ -107,7 +107,6 @@ extern BOOL GSScanDouble(unichar*, unsigned, double*); @interface GSImmutableString : NSObject // Help the compiler @end - /* * Cache classes and method implementations for speed. */ @@ -454,7 +453,6 @@ surrogatePairValue(unichar high, unichar low) + ((low - (unichar)0xDC00) + (unichar)10000); } - @implementation NSString // NSString itself is an abstract class which provides factory // methods to generate objects of unspecified subclasses. @@ -566,8 +564,8 @@ handle_printf_atsign (FILE *stream, gcrSel = @selector(getCharacters:range:); ranSel = @selector(rangeOfComposedCharacterSequenceAtIndex:); - _DefaultStringEncoding = GetDefEncoding(); - _ByteEncodingOk = GSIsByteEncoding(_DefaultStringEncoding); + _DefaultStringEncoding = GSPrivateDefaultCStringEncoding(); + _ByteEncodingOk = GSPrivateIsByteEncoding(_DefaultStringEncoding); NSStringClass = self; [self setVersion: 1]; @@ -1057,7 +1055,6 @@ handle_printf_atsign (FILE *stream, locale: (NSDictionary*)locale arguments: (va_list)argList { - extern void GSStrExternalize(); unsigned char buf[2048]; GSStr_t f; unichar fbuf[1024]; @@ -1080,7 +1077,7 @@ handle_printf_atsign (FILE *stream, /* * Now set up 'f' as a GSMutableString object whose initial buffer is - * allocated on the stack. The GSFormat function can write into it. + * allocated on the stack. The GSPrivateFormat function can write into it. */ f.isa = GSMutableStringClass; f._zone = NSDefaultMallocZone(); @@ -1089,8 +1086,8 @@ handle_printf_atsign (FILE *stream, f._count = 0; f._flags.wide = 0; f._flags.free = 0; - GSFormat(&f, fmt, argList, locale); - GSStrExternalize(&f); + GSPrivateFormat(&f, fmt, argList, locale); + GSPrivateStrExternalize(&f); if (fmt != fbuf) { objc_free(fmt); @@ -2567,7 +2564,15 @@ handle_printf_atsign (FILE *stream, unsigned length = [d length]; BOOL result = (length <= maxLength) ? YES : NO; - if (length > maxLength) length = maxLength; + if (d == nil) + { + [NSException raise: NSCharacterConversionException + format: @"Can't convert to C string."]; + } + if (length > maxLength) + { + length = maxLength; + } memcpy(buffer, [d bytes], length); buffer[length] = '\0'; return result; @@ -2694,7 +2699,7 @@ handle_printf_atsign (FILE *stream, */ + (NSStringEncoding*) availableStringEncodings { - return GetAvailableEncodings(); + return GSPrivateAvailableEncodings(); } /** @@ -2712,7 +2717,7 @@ handle_printf_atsign (FILE *stream, */ ourbundle = [NSBundle bundleForLibrary: @"gnustep-base"]; - ourname = GetEncodingName(encoding); + ourname = GSPrivateEncodingName(encoding); return [ourbundle localizedStringForKey: ourname value: ourname table: nil]; @@ -3085,9 +3090,37 @@ static NSFileManager *fm = nil; unsigned originalLength = [self length]; unsigned length = originalLength; unsigned aLength = [aString length]; - unsigned root = rootOf(aString, aLength); + unsigned root; unichar buf[length+aLength+1]; + /* If the 'component' has a leading path separator (or drive spec + * in windows) then we need to find its length so we can strip it. + */ + root = rootOf(aString, aLength); + if (root > 0) + { + unichar c = [aString characterAtIndex: 0]; + + if (c == '~') + { + root = 0; + } + else if (root > 1 && pathSepMember(c)) + { + int i; + + for (i = 1; i < root; i++) + { + c = [aString characterAtIndex: i]; + if (!pathSepMember(c)) + { + break; + } + } + root = i; + } + } + if (length == 0) { [aString getCharacters: buf range: ((NSRange){0, aLength})]; @@ -3190,11 +3223,11 @@ static NSFileManager *fm = nil; } /* MacOS-X prohibits an extension beginning with a path separator, - * but this code extends that a little to prohibit any root from - * being used as an extension. Perhaps we should be more permissive? + * but this code extends that a little to prohibit any root except + * one beginning with '~' from being used as an extension. */ root = rootOf(aString, [aString length]); - if (root > 0) + if (root > 0 && [aString characterAtIndex: 0] != '~') { NSLog(@"[%@-%@] cannot append extension '%@' to path '%@'", NSStringFromClass([self class]), NSStringFromSelector(_cmd), @@ -4151,7 +4184,6 @@ static NSFileManager *fm = nil; { va_list ap; id ret; - NSDictionary *dict; va_start(ap, format); if (format == nil) @@ -4160,9 +4192,8 @@ static NSFileManager *fm = nil; } else { - dict = GSUserDefaultsDictionaryRepresentation(); ret = AUTORELEASE([[self allocWithZone: NSDefaultMallocZone()] - initWithFormat: format locale: dict arguments: ap]); + initWithFormat: format locale: GSPrivateDefaultLocale() arguments: ap]); } va_end(ap); return ret; @@ -4212,12 +4243,10 @@ static NSFileManager *fm = nil; */ - (NSComparisonResult) localizedCompare: (NSString *)string { - NSDictionary *dict = GSUserDefaultsDictionaryRepresentation(); - return [self compare: string options: 0 range: ((NSRange){0, [self length]}) - locale: dict]; + locale: GSPrivateDefaultLocale()]; } /** @@ -4226,12 +4255,10 @@ static NSFileManager *fm = nil; */ - (NSComparisonResult) localizedCaseInsensitiveCompare: (NSString *)string { - NSDictionary *dict = GSUserDefaultsDictionaryRepresentation(); - return [self compare: string options: NSCaseInsensitiveSearch range: ((NSRange){0, [self length]}) - locale: dict]; + locale: GSPrivateDefaultLocale()]; } /** diff --git a/Source/NSTask.m b/Source/NSTask.m index 53717b9bb..5f8cb72fd 100644 --- a/Source/NSTask.m +++ b/Source/NSTask.m @@ -47,6 +47,7 @@ #include "Foundation/NSTimer.h" #include "Foundation/NSLock.h" #include "Foundation/NSDebug.h" +#include "GSPrivate.h" #include #ifdef HAVE_UNISTD_H @@ -921,7 +922,7 @@ pty_slave(const char* name) @implementation NSConcreteWindowsTask BOOL -GSCheckTasks() +GSPrivateCheckTasks() { BOOL found = NO; @@ -1197,7 +1198,8 @@ quotedFromString(NSString *aString) NULL, /* proc attrs */ NULL, /* thread attrs */ 1, /* inherit handles */ - CREATE_NO_WINDOW|DETACHED_PROCESS|CREATE_UNICODE_ENVIRONMENT, +// CREATE_NO_WINDOW|DETACHED_PROCESS|CREATE_UNICODE_ENVIRONMENT, + CREATE_NO_WINDOW|CREATE_UNICODE_ENVIRONMENT, envp, /* env block */ (const unichar*)[[self currentDirectoryPath] fileSystemRepresentation], &start_info, @@ -1256,7 +1258,7 @@ quotedFromString(NSString *aString) @implementation NSConcreteUnixTask BOOL -GSCheckTasks() +GSPrivateCheckTasks() { BOOL found = NO; @@ -1276,6 +1278,7 @@ GSCheckTasks() [tasksLock lock]; t = (NSTask*)NSMapGet(activeTasks, (void*)(intptr_t)result); + AUTORELEASE(RETAIN(t)); [tasksLock unlock]; if (t != nil) { @@ -1561,8 +1564,8 @@ GSCheckTasks() result = waitpid(_taskId, &_terminationStatus, WNOHANG); if (result < 0) { - NSLog(@"waitpid %d, result %d, error %s", - _taskId, result, GSLastErrorStr(errno)); + NSLog(@"waitpid %d, result %d, error %@", + _taskId, result, [NSError _last]); [self _terminatedChild: -1]; } else if (result == _taskId || (result > 0 && errno == 0)) @@ -1594,8 +1597,8 @@ GSCheckTasks() #ifdef WAITDEBUG else { - NSLog(@"waitpid %d, result %d, error %s", - _taskId, result, GSLastErrorStr(errno)); + NSLog(@"waitpid %d, result %d, error %@", + _taskId, result, [NSError _last]); } #endif } diff --git a/Source/NSThread.m b/Source/NSThread.m index 429f1f5dc..abe938591 100644 --- a/Source/NSThread.m +++ b/Source/NSThread.m @@ -49,11 +49,13 @@ #include "Foundation/NSThread.h" #include "Foundation/NSLock.h" #include "Foundation/NSString.h" +#include "Foundation/NSNotification.h" #include "Foundation/NSNotificationQueue.h" #include "Foundation/NSRunLoop.h" #include "Foundation/NSConnection.h" #include "Foundation/NSInvocation.h" +#include "GSPrivate.h" #include "GSRunLoopCtxt.h" @interface NSAutoreleasePool (NSThread) @@ -889,12 +891,12 @@ static NSDate *theFuture; #if defined(__MINGW32__) if (SetEvent(event) == 0) { - NSLog(@"Set event failed - %@", GSLastErrorStr(errno)); + NSLog(@"Set event failed - %@", [NSError _last]); } #else if (write(outputFd, "0", 1) != 1) { - NSLog(@"Write to pipe failed - %@", GSLastErrorStr(errno)); + NSLog(@"Write to pipe failed - %@", [NSError _last]); } #endif @@ -918,12 +920,12 @@ static NSDate *theFuture; #if defined(__MINGW32__) if (ResetEvent(event) == 0) { - NSLog(@"Reset event failed - %@", GSLastErrorStr(errno)); + NSLog(@"Reset event failed - %@", [NSError _last]); } #else if (read(inputFd, &c, 1) != 1) { - NSLog(@"Read pipe failed - %@", GSLastErrorStr(errno)); + NSLog(@"Read pipe failed - %@", [NSError _last]); } #endif diff --git a/Source/NSTimeZone.m b/Source/NSTimeZone.m index 9dae3f8f1..dfc1b9700 100644 --- a/Source/NSTimeZone.m +++ b/Source/NSTimeZone.m @@ -21,7 +21,8 @@ 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., 51 Franklin Street, Fifth Floor, Boston, MA 02111 USA. + Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02111 USA. NSTimeZone class reference $Date$ $Revision$ @@ -58,13 +59,13 @@ =================================== Default place for the NSTimeZone directory is _time_zone_path(): - {$(GNUSTEP_SYSTEM_ROOT)Libary/Libraries/Resources/TIME_ZONE_DIR} + {$(GNUSTEP_SYSTEM_LIBRARY)/Libraries/gnustep-base/Versions/1.14/Resources/TIME_ZONE_DIR) LOCAL_TIME_FILE is a text file with the name of the time zone file. ZONES_DIR is a sub-directory under TIME_ZONE_DIR - (dir) ../System/Library/Libraries/Resources/.. + (dir) ../System/Library/Libraries/gnustep-base/Versions/1.14/Resources/.. (dir) NSTimeZone (file) localtime {text; time zone eg Australia/Perth} (dir) zones @@ -106,7 +107,7 @@ #include "Foundation/NSByteOrder.h" #include "Foundation/NSDebug.h" #include "GNUstepBase/GSCategories.h" -#include "GSConfig.h" +#include "GNUstepBase/GSConfig.h" #include "GSPrivate.h" #ifdef HAVE_TZHEAD @@ -272,7 +273,7 @@ static NSString *_time_zone_path(NSString *subpath, NSString *type) NSBundle *gbundle; if (type == nil) type = @""; - gbundle = [NSBundle bundleForLibrary: @"gnustep-base"]; + gbundle = [NSBundle bundleForClass: [NSObject class]]; return [gbundle pathForResource: subpath ofType: type inDirectory: TIME_ZONE_DIR]; @@ -464,15 +465,6 @@ static NSString *_time_zone_path(NSString *subpath, NSString *type) if (data == nil) { NSString *fileName; - const char *str = [name UTF8String]; - - /* Make sure that only time zone files are accessed. - FIXME: Make this more robust. */ - if ((str)[0] == '/' || strchr(str, '.') != NULL) - { - NSLog(@"Disallowed time zone name `%@'.", name); - return nil; - } fileName = [NSTimeZoneClass getTimeZoneFile: name]; if (fileName == nil @@ -1468,38 +1460,22 @@ static NSMapTable *absolutes = 0; #if defined(__MINGW32__) /* - * Try to get timezone from windows registry. + * Try to get timezone from windows system call. */ { - HKEY regkey; + TIME_ZONE_INFORMATION tz; + DWORD DST = GetTimeZoneInformation(&tz); - if (ERROR_SUCCESS == RegOpenKeyExA(HKEY_LOCAL_MACHINE, - "SYSTEM\\CurrentControlSet\\Control\\TimeZoneInformation", - 0, - KEY_READ, - ®key)) - { - char buf[255]; - DWORD bufsize=255; - DWORD type; - - if (ERROR_SUCCESS == RegQueryValueExA(regkey, - "StandardName", - 0, - &type, - buf, - &bufsize)) - { - bufsize = strlen(buf); - while (bufsize && isspace(buf[bufsize-1])) - { - bufsize--; - } - localZoneString - = [NSString stringWithCString: buf length: bufsize]; - } - RegCloseKey(regkey); - } + if (DST == TIME_ZONE_ID_DAYLIGHT) + { + localZoneString = [NSString stringWithCharacters: tz.DaylightName + length: wcslen(tz.DaylightName)]; + } + else + { + localZoneString = [NSString stringWithCharacters: tz.StandardName + length: wcslen(tz.StandardName)]; + } } #endif @@ -2362,12 +2338,36 @@ GSBreakTime(NSTimeInterval when, int *year, int *month, int *day, GSBreakTime(when, &year, &month, &day, &hour, &minute, &second, &mil); - // Before April or after October is Std - if (month < DaylightDate.wMonth || month > StandardDate.wMonth) - return NO; - // After April and before October is DST - if (month > DaylightDate.wMonth && month < StandardDate.wMonth) - return YES; + // Check north globe + if (StandardDate.wMonth >= DaylightDate.wMonth) + { + // Before April or after October is Std + if (month < DaylightDate.wMonth || month > StandardDate.wMonth) + { + return NO; + } + // After April and before October is DST + if (month > DaylightDate.wMonth && month < StandardDate.wMonth) + { + return YES; + } + } + else + { + /* check south globe + * Before April or after October is DST + */ + if (month < StandardDate.wMonth || month > DaylightDate.wMonth) + { + return YES; + } + // After April and before October is Std + if (month > StandardDate.wMonth && month < DaylightDate.wMonth) + { + return NO; + } + } + dow = ((int)((when / 86400.0) + GREGORIAN_REFERENCE)) % 7; if (dow < 0) dow += 7; @@ -2405,7 +2405,7 @@ GSBreakTime(NSTimeInterval when, int *year, int *month, int *day, if (mil >= DaylightDate.wMilliseconds) return YES; return NO; - } + } if (month == StandardDate.wMonth /* October */) { daylightdate = day - dow + StandardDate.wDayOfWeek; @@ -2445,7 +2445,17 @@ GSBreakTime(NSTimeInterval when, int *year, int *month, int *day, - (NSString*) name { - return timeZoneName; + TIME_ZONE_INFORMATION tz; + DWORD DST = GetTimeZoneInformation(&tz); + + if (DST == TIME_ZONE_ID_DAYLIGHT) + { + return daylightZoneName; + } + else + { + return timeZoneName; + } } - (int) secondsFromGMTForDate: (NSDate*)aDate @@ -2495,7 +2505,7 @@ GSBreakTime(NSTimeInterval when, int *year, int *month, int *day, - (NSString*) timeZoneName { - return timeZoneName; + return [self name]; } @end #endif // __MINGW32__ diff --git a/Source/NSTimer.m b/Source/NSTimer.m index 18401bb88..222de7cbe 100644 --- a/Source/NSTimer.m +++ b/Source/NSTimer.m @@ -20,7 +20,8 @@ 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., 51 Franklin Street, Fifth Floor, Boston, MA 02111 USA. + Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02111 USA. NSTimer class reference $Date$ $Revision$ @@ -121,7 +122,7 @@ static Class NSDate_class; /** * Create a timer which will fire after ti seconds and, if f is YES, * every ti seconds thereafter. On firing, the target object will be - * sent a message specified by selector and with the value info as an + * sent a message specified by selector and with the timer as its * argument.
* NB. To make the timer operate, you must add it to a run loop. */ @@ -149,17 +150,21 @@ static Class NSDate_class; invocation: (NSInvocation*)invocation repeats: (BOOL)f { - id t = [self timerWithTimeInterval: ti - invocation: invocation - repeats: f]; + id t = [[self alloc] initWithFireDate: nil + interval: ti + target: invocation + selector: NULL + userInfo: nil + repeats: f]; [[NSRunLoop currentRunLoop] addTimer: t forMode: NSDefaultRunLoopMode]; + RELEASE(t); return t; } /** * Create a timer which will fire after ti seconds and, if f is YES, * every ti seconds thereafter. On firing, the target object will be - * sent a message specified by selector and with the object info as an + * sent a message specified by selector and with the timer as its * argument.
* This timer will automatically be added to the current run loop and * will fire in the default run loop mode. @@ -170,12 +175,14 @@ static Class NSDate_class; userInfo: (id)info repeats: (BOOL)f { - id t = [self timerWithTimeInterval: ti - target: object - selector: selector - userInfo: info - repeats: f]; + id t = [[self alloc] initWithFireDate: nil + interval: ti + target: object + selector: selector + userInfo: info + repeats: f]; [[NSRunLoop currentRunLoop] addTimer: t forMode: NSDefaultRunLoopMode]; + RELEASE(t); return t; } diff --git a/Source/NSURLAuthenticationChallenge.m b/Source/NSURLAuthenticationChallenge.m index 901b75c6b..b7ae4e432 100644 --- a/Source/NSURLAuthenticationChallenge.m +++ b/Source/NSURLAuthenticationChallenge.m @@ -23,6 +23,7 @@ */ #include "GSURLPrivate.h" +#include "Foundation/NSError.h" // Internal data storage diff --git a/Source/NSUndoManager.m b/Source/NSUndoManager.m index 0a40aa7b7..b7f82b8a5 100644 --- a/Source/NSUndoManager.m +++ b/Source/NSUndoManager.m @@ -17,7 +17,8 @@ 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., 51 Franklin Street, Fifth Floor, Boston, MA 02111 USA. + Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02111 USA. NSUndoManager class reference $Date$ $Revision$ diff --git a/Source/NSUserDefaults.m b/Source/NSUserDefaults.m index 23a513324..aad59c0d6 100644 --- a/Source/NSUserDefaults.m +++ b/Source/NSUserDefaults.m @@ -36,7 +36,6 @@ #include "Foundation/NSUserDefaults.h" #include "Foundation/NSArchiver.h" #include "Foundation/NSArray.h" -#include "Foundation/NSBundle.h" #include "Foundation/NSData.h" #include "Foundation/NSDate.h" #include "Foundation/NSDictionary.h" @@ -261,13 +260,6 @@ static BOOL setSharedDefaults = NO; /* Flag to prevent infinite recursion */ } } -/** - * Resets the shared user defaults object to reflect the current - * user ID. Needed by setuid processes which change the user they - * are running as.
- * In GNUstep you should call GSSetUserName() when changing your - * effective user ID, and that function will call this function for you. - */ + (void) resetStandardUserDefaults { [classLock lock]; @@ -278,7 +270,11 @@ static BOOL setSharedDefaults = NO; /* Flag to prevent infinite recursion */ [sharedDefaults synchronize]; // Ensure changes are written. regDefs = RETAIN([sharedDefaults->_tempDomains objectForKey: NSRegistrationDomain]); - + /* To ensure that we don't try to synchronise the old defaults to disk + * after creating the new ones, remove as housekeeping notification + * observer. + */ + [[NSNotificationCenter defaultCenter] removeObserver: sharedDefaults]; setSharedDefaults = NO; DESTROY(sharedDefaults); if (regDefs != nil) @@ -401,16 +397,9 @@ static BOOL setSharedDefaults = NO; /* Flag to prevent infinite recursion */ return registrationDefaults; } -/** - * Returns the shared defaults object. If it doesn't exist yet, it's - * created. The defaults are initialized for the current user. - * The search list is guaranteed to be standard only the first time - * this method is invoked. The shared instance is provided as a - * convenience; other instances may also be created. - */ + (NSUserDefaults*) standardUserDefaults { - BOOL added_locale, added_lang; + BOOL added_lang, added_locale; id lang; NSArray *uL; NSEnumerator *enumerator; @@ -503,63 +492,129 @@ static BOOL setSharedDefaults = NO; /* Flag to prevent infinite recursion */ } /* Set up language constants */ - added_locale = NO; - added_lang = NO; - enumerator = [uL objectEnumerator]; - while ((lang = [enumerator nextObject])) - { - NSString *path; - NSDictionary *dict; - NSBundle *gbundle; - gbundle = [NSBundle bundleForLibrary: @"gnustep-base"]; - path = [gbundle pathForResource: lang - ofType: nil - inDirectory: @"Languages"]; - dict = nil; - if (path != nil) - { - dict = [NSDictionary dictionaryWithContentsOfFile: path]; - } - if (dict) - { - [sharedDefaults setVolatileDomain: dict forName: lang]; - added_lang = YES; - } - else if (added_locale == NO) - { - NSString *locale = nil; + /* We lookup gnustep-base resources manually here to prevent + * bootstrap problems. NSBundle's lookup routines depend on having + * NSUserDefaults already bootstrapped, but we're still + * bootstrapping here! So we can't really use NSBundle without + * incurring massive bootstrap complications (btw, most of the times + * we're here as a consequence of [NSBundle +initialize] creating + * the gnustep-base bundle! So trying to use the gnustep-base + * bundle here wouldn't really work.). + */ + /* + * We are looking for: + * + * GNUSTEP_LIBRARY/Libraries/gnustep-base/Versions//Resources/Languages/ + * + * We iterate over , and for each we iterate over GNUSTEP_LIBRARY. + */ + + { + /* These variables are reused for all languages so we set them up + * once here and then reuse them. + */ + NSFileManager *fm = [NSFileManager defaultManager]; + NSString *tail = [[[[[@"Libraries" + stringByAppendingPathComponent: @"gnustep-base"] + stringByAppendingPathComponent: @"Versions"] + stringByAppendingPathComponent: + OBJC_STRINGIFY(GNUSTEP_BASE_MAJOR_VERSION.GNUSTEP_BASE_MINOR_VERSION)] + stringByAppendingPathComponent: @"Resources"] + stringByAppendingPathComponent: @"Languages"]; + NSArray *paths = NSSearchPathForDirectoriesInDomains (NSLibraryDirectory, + NSAllDomainsMask, YES); + + added_lang = NO; + added_locale = NO; + enumerator = [uL objectEnumerator]; + while ((lang = [enumerator nextObject])) + { + NSDictionary *dict = nil; + NSString *path = nil; + NSEnumerator *pathEnumerator = [paths objectEnumerator]; + while ((path = [pathEnumerator nextObject]) != nil) + { + path = [[path stringByAppendingPathComponent: tail] + stringByAppendingPathComponent: lang]; + + if ([fm fileExistsAtPath: path]) + { + /* Path found! */ + break; + } + } + + if (path != nil) + { + dict = [NSDictionary dictionaryWithContentsOfFile: path]; + } + if (dict != nil) + { + [sharedDefaults setVolatileDomain: dict forName: lang]; + added_lang = YES; + } + else if (added_locale == NO) + { + /* The resources for the language that we were looking for + * were not found. If this was the currently set locale + * in the C library, try to get the same information from + * the C library. This would usually happen for the + * language that was added to the list of languages + * precisely because it is the currently set locale in the + * C library. + */ + NSString *locale = nil; + #ifdef HAVE_LOCALE_H #ifdef LC_MESSAGES - locale = GSSetLocale(LC_MESSAGES, nil); + locale = GSSetLocale(LC_MESSAGES, nil); #endif #endif - if (locale == nil) - { - continue; - } - /* See if we can get the dictionary from i18n functions. - Note that we get the dict from the current locale regardless - of what 'lang' is, since it should match anyway. */ - /* Also, I don't think that the i18n routines can handle more than - one locale, but tell me if I'm wrong... */ - if (GSLanguageFromLocale(locale)) - { - lang = GSLanguageFromLocale(locale); - } - dict = GSDomainFromDefaultLocale(); - if (dict != nil) - { - [sharedDefaults setVolatileDomain: dict forName: lang]; - } - added_locale = YES; - } - } + if (locale != nil) + { + /* See if we can get the dictionary from i18n + * functions. I don't think that the i18n routines + * can handle more than one locale, so we don't try to + * look 'lang' up but just get what we get and use it + * if it matches 'lang' ... but tell me if I'm wrong + * ... + */ + if ([lang isEqualToString: GSLanguageFromLocale (locale)]) + { + /* We set added_locale to YES to avoid so that we + * won't do this C library locale lookup again + * later on. + */ + added_locale = YES; + + dict = GSDomainFromDefaultLocale (); + if (dict != nil) + { + [sharedDefaults setVolatileDomain: dict forName: lang]; + + /* We do not set added_lang to YES here + * because we want the improper installation + * warning to be printed below if our own + * English language dictionary is not found, + * and we want the basic hardcoded defaults to + * be used in that case. (FIXME: Review this + * decision). + */ + } + } + } + } + } + } + if (added_lang == NO) { - /* Ack! We should never get here */ + /* Ack! We should never get here. */ NSWarnMLog(@"Improper installation: No language locale found"); + + /* FIXME - should we set this as volatile domain for English ? */ [sharedDefaults registerDefaults: [self _unlocalizedDefaults]]; } RETAIN(sharedDefaults); @@ -568,12 +623,6 @@ static BOOL setSharedDefaults = NO; /* Flag to prevent infinite recursion */ return AUTORELEASE(sharedDefaults); } -/** - * Returns the array of user languages preferences. Uses the - * NSLanguages user default if available, otherwise - * tries to infer setup from operating system information etc - * (in particular, uses the LANGUAGES environment variable). - */ + (NSArray*) userLanguages { NSArray *result; @@ -620,7 +669,7 @@ static BOOL setSharedDefaults = NO; /* Flag to prevent infinite recursion */ #endif #endif currLang = [[NSUserDefaults standardUserDefaults] - stringArrayForKey: @"NSLanguages"]; + stringArrayForKey: @"NSLanguages"]; userLanguages = [[NSMutableArray alloc] initWithCapacity: 5]; @@ -685,10 +734,6 @@ static BOOL setSharedDefaults = NO; /* Flag to prevent infinite recursion */ return AUTORELEASE(result); } -/** - * Sets the array of user languages preferences. Places the specified - * array in the NSLanguages user default. - */ + (void) setUserLanguages: (NSArray*)languages { NSMutableDictionary *globDict; @@ -704,20 +749,11 @@ static BOOL setSharedDefaults = NO; /* Flag to prevent infinite recursion */ RELEASE(globDict); } -/************************************************************************* - *** Initializing the User Defaults - *************************************************************************/ -/** - * Initializes defaults for current user calling initWithUser: - */ - (id) init { return [self initWithUser: NSUserName()]; } -/** - * Initializes defaults for the specified user calling -initWithContentsOfFile: - */ - (id) initWithUser: (NSString*)userName { NSString *path; @@ -727,11 +763,6 @@ static BOOL setSharedDefaults = NO; /* Flag to prevent infinite recursion */ return [self initWithContentsOfFile: path]; } -/** - * - * Initializes defaults for the specified path. Returns an object with - * an empty search list. - */ - (id) initWithContentsOfFile: (NSString*)path { NSFileManager *mgr = [NSFileManager defaultManager]; @@ -746,7 +777,9 @@ static BOOL setSharedDefaults = NO; /* Flag to prevent infinite recursion */ */ if (processName == nil) { - processName = RETAIN([[NSProcessInfo processInfo] processName]); + NSString *s = [[NSProcessInfo processInfo] processName]; + + processName = [s copy]; } if (path == nil || [path isEqual: @""] == YES) @@ -867,11 +900,6 @@ static BOOL setSharedDefaults = NO; /* Flag to prevent infinite recursion */ return desc; } -/** - * Adds the domain names aName to the search list of the receiver.
- * The domain is added after the application domain.
- * Suites may be removed using the -removeSuiteNamed: method. - */ - (void) addSuiteNamed: (NSString*)aName { unsigned index; @@ -893,10 +921,6 @@ static BOOL setSharedDefaults = NO; /* Flag to prevent infinite recursion */ RELEASE(aName); } -/** - * Looks up a value for a specified default using -objectForKey: - * and checks that it is an NSArray object. Returns nil if it is not. - */ - (NSArray*) arrayForKey: (NSString*)defaultName { id obj = [self objectForKey: defaultName]; @@ -906,16 +930,6 @@ static BOOL setSharedDefaults = NO; /* Flag to prevent infinite recursion */ return nil; } -/** - * Looks up a value for a specified default using -objectForKey: - * and returns its boolean representation.
- * Returns NO if it is not a boolean.
- * The text 'yes' or 'true' or any non zero numeric value is considered - * to be a boolean YES. Other string values are NO.
- * NB. This differs slightly from the documented behavior for MacOS-X - * (August 2002) in that the GNUstep version accepts the string 'TRUE' - * as equivalent to 'YES'. - */ - (BOOL) boolForKey: (NSString*)defaultName { id obj = [self objectForKey: defaultName]; @@ -928,10 +942,6 @@ static BOOL setSharedDefaults = NO; /* Flag to prevent infinite recursion */ return NO; } -/** - * Looks up a value for a specified default using -objectForKey: - * and checks that it is an NSData object. Returns nil if it is not. - */ - (NSData*) dataForKey: (NSString*)defaultName { id obj = [self objectForKey: defaultName]; @@ -941,10 +951,6 @@ static BOOL setSharedDefaults = NO; /* Flag to prevent infinite recursion */ return nil; } -/** - * Looks up a value for a specified default using -objectForKey: - * and checks that it is an NSDictionary object. Returns nil if it is not. - */ - (NSDictionary*) dictionaryForKey: (NSString*)defaultName { id obj = [self objectForKey: defaultName]; @@ -956,10 +962,6 @@ static BOOL setSharedDefaults = NO; /* Flag to prevent infinite recursion */ return nil; } -/** - * Looks up a value for a specified default using -objectForKey: - * and checks that it is a float. Returns 0.0 if it is not. - */ - (float) floatForKey: (NSString*)defaultName { id obj = [self objectForKey: defaultName]; @@ -972,10 +974,6 @@ static BOOL setSharedDefaults = NO; /* Flag to prevent infinite recursion */ return 0.0; } -/** - * Looks up a value for a specified default using -objectForKey: - * and checks that it is an integer. Returns 0 if it is not. - */ - (int) integerForKey: (NSString*)defaultName { id obj = [self objectForKey: defaultName]; @@ -988,12 +986,6 @@ static BOOL setSharedDefaults = NO; /* Flag to prevent infinite recursion */ return 0; } -/** - * Looks up a value for a specified default using. - * The lookup is performed by accessing the domains in the order - * given in the search list. - *
Returns nil if defaultName cannot be found. - */ - (id) objectForKey: (NSString*)defaultName { NSEnumerator *enumerator; @@ -1026,10 +1018,6 @@ static BOOL setSharedDefaults = NO; /* Flag to prevent infinite recursion */ return AUTORELEASE(object); } -/** - * Removes the default with the specified name from the application - * domain. - */ - (void) removeObjectForKey: (NSString*)defaultName { id obj; @@ -1057,11 +1045,6 @@ static BOOL setSharedDefaults = NO; /* Flag to prevent infinite recursion */ [_lock unlock]; } -/** - * Sets a boolean value for defaultName in the application domain.
- * The boolean value is stored as a string - either YES or NO. - * Calls -setObject:forKey: to make the change. - */ - (void) setBool: (BOOL)value forKey: (NSString*)defaultName { NSNumber *n = [NSNumberClass numberWithBool: value]; @@ -1069,10 +1052,6 @@ static BOOL setSharedDefaults = NO; /* Flag to prevent infinite recursion */ [self setObject: n forKey: defaultName]; } -/** - * Sets a float value for defaultName in the application domain. - *
Calls -setObject:forKey: to make the change. - */ - (void) setFloat: (float)value forKey: (NSString*)defaultName { NSNumber *n = [NSNumberClass numberWithFloat: value]; @@ -1080,10 +1059,6 @@ static BOOL setSharedDefaults = NO; /* Flag to prevent infinite recursion */ [self setObject: n forKey: defaultName]; } -/** - * Sets an integer value for defaultName in the application domain. - *
Calls -setObject:forKey: to make the change. - */ - (void) setInteger: (int)value forKey: (NSString*)defaultName { NSNumber *n = [NSNumberClass numberWithInt: value]; @@ -1145,17 +1120,6 @@ static BOOL isPlistObject(id o) return NO; } -/** - * Sets an object value for defaultName in the application domain.
- * The defaultName must be a non-empty string.
- * The value must be an instance of one of the [NSString-propertyList] - * classes.
- *

Causes a NSUserDefaultsDidChangeNotification to be posted - * if this is the first change to a persistent-domain since the - * last -synchronize. - *

- * If value is nil, this is equivalent to the -removeObjectForKey: method. - */ - (void) setObject: (id)value forKey: (NSString*)defaultName { NSMutableDictionary *dict; @@ -1174,8 +1138,8 @@ static BOOL isPlistObject(id o) if (isPlistObject(value) == NO) { [NSException raise: NSInvalidArgumentException - format: @"attempt to set non property list object for key (%@)", - defaultName]; + format: @"attempt to set non property list object (%@) for key (%@)", + value, defaultName]; } [_lock lock]; @@ -1195,10 +1159,6 @@ static BOOL isPlistObject(id o) [_lock unlock]; } -/** - * Calls -arrayForKey: to get an array value for defaultName and checks - * that the array contents are string objects ... if not, returns nil. - */ - (NSArray*) stringArrayForKey: (NSString*)defaultName { id arr = [self arrayForKey: defaultName]; @@ -1220,10 +1180,6 @@ static BOOL isPlistObject(id o) return nil; } -/** - * Looks up a value for a specified default using -objectForKey: - * and checks that it is an NSString. Returns nil if it is not. - */ - (NSString*) stringForKey: (NSString*)defaultName { id obj = [self objectForKey: defaultName]; @@ -1233,15 +1189,6 @@ static BOOL isPlistObject(id o) return nil; } -/************************************************************************* - *** Returning the Search List - *************************************************************************/ - -/** - * Returns an array listing the domains searched in order to look up - * a value in the defaults system. The order of the names in the - * array is the order in which the domains are searched. - */ - (NSArray*) searchList { NSArray *copy; @@ -1252,12 +1199,6 @@ static BOOL isPlistObject(id o) return AUTORELEASE(copy); } -/** - * Sets the list of the domains searched in order to look up - * a value in the defaults system. The order of the names in the - * array is the order in which the domains are searched.
- * On lookup, the first match is used. - */ - (void) setSearchList: (NSArray*)newList { [_lock lock]; @@ -1268,9 +1209,6 @@ static BOOL isPlistObject(id o) [_lock unlock]; } -/** - * Returns the persistent domain specified by domainName. - */ - (NSDictionary*) persistentDomainForName: (NSString*)domainName { NSDictionary *copy; @@ -1281,9 +1219,6 @@ static BOOL isPlistObject(id o) return AUTORELEASE(copy); } -/** - * Returns an array listing the name of all the persistent domains. - */ - (NSArray*) persistentDomainNames { NSArray *keys; @@ -1294,13 +1229,6 @@ static BOOL isPlistObject(id o) return keys; } -/** - * Removes the persistent domain specified by domainName from the - * user defaults. - *
Causes a NSUserDefaultsDidChangeNotification to be posted - * if this is the first change to a persistent-domain since the - * last -synchronize. - */ - (void) removePersistentDomainForName: (NSString*)domainName { [_lock lock]; @@ -1312,15 +1240,6 @@ static BOOL isPlistObject(id o) [_lock unlock]; } -/** - * Replaces the persistent-domain specified by domainName with - * domain ... a dictionary containing keys and defaults values. - *
Raises an NSInvalidArgumentException if domainName already - * exists as a volatile-domain. - *
Causes a NSUserDefaultsDidChangeNotification to be posted - * if this is the first change to a persistent-domain since the - * last -synchronize. - */ - (void) setPersistentDomain: (NSDictionary*)domain forName: (NSString*)domainName { @@ -1573,13 +1492,6 @@ static BOOL isLocked = NO; return YES; } -/** - * Ensures that the in-memory and on-disk representations of the defaults - * are in sync. You may call this yourself, but probably don't need to - * since it is invoked at intervals whenever a runloop is running.
- * If any persistent domain is changed by reading new values from disk, - * an NSUserDefaultsDidChangeNotification is posted. - */ - (BOOL) synchronize { NSMutableDictionary *newDict; @@ -1679,10 +1591,6 @@ static BOOL isLocked = NO; } -/** - * Removes the volatile domain specified by domainName from the - * user defaults. - */ - (void) removeVolatileDomainForName: (NSString*)domainName { [_lock lock]; @@ -1692,12 +1600,6 @@ static BOOL isLocked = NO; [_lock unlock]; } -/** - * Sets the volatile-domain specified by domainName to - * domain ... a dictionary containing keys and defaults values.
- * Raises an NSInvalidArgumentException if domainName already - * exists as either a volatile-domain or a persistent-domain. - */ - (void) setVolatileDomain: (NSDictionary*)domain forName: (NSString*)domainName { @@ -1727,9 +1629,6 @@ static BOOL isLocked = NO; [_lock unlock]; } -/** - * Returns the volatile domain specified by domainName. - */ - (NSDictionary*) volatileDomainForName: (NSString*)domainName { NSDictionary *copy; @@ -1740,9 +1639,6 @@ static BOOL isLocked = NO; return AUTORELEASE(copy); } -/** - * Returns an array listing the name of all the volatile domains. - */ - (NSArray*) volatileDomainNames { NSArray *keys; @@ -1753,11 +1649,6 @@ static BOOL isLocked = NO; return keys; } -/** - * Returns a dictionary representing the current state of the defaults - * system ... this is a merged version of all the domains in the - * search list. - */ - (NSDictionary*) dictionaryRepresentation { NSDictionary *rep; @@ -1798,13 +1689,6 @@ static BOOL isLocked = NO; return AUTORELEASE(rep); } -/** - * Merges the contents of the dictionary newVals into the registration - * domain. Registration defaults may be added to or replaced using this - * method, but may never be removed. Thus, setting registration defaults - * at any point in your program guarantees that the defaults will be - * available thereafter. - */ - (void) registerDefaults: (NSDictionary*)newVals { NSMutableDictionary *regDefs; @@ -1823,10 +1707,6 @@ static BOOL isLocked = NO; [_lock unlock]; } -/** - * Removes the named domain from the search list of the receiver.
- * Suites may be added using the -addSuiteNamed: method. - */ - (void) removeSuiteNamed: (NSString*)aName { if (aName == nil) @@ -1956,26 +1836,8 @@ static BOOL isLocked = NO; } @end -NSDictionary* -GSUserDefaultsDictionaryRepresentation() -{ - NSDictionary *defs; - - if (sharedDefaults == nil) - { - [NSUserDefaults standardUserDefaults]; - } - [classLock lock]; - defs = [sharedDefaults dictionaryRepresentation]; - [classLock unlock]; - return defs; -} - -/* - * Get one of several potentially useful flags. - */ BOOL -GSUserDefaultsFlag(GSUserDefaultFlagType type) +GSPrivateDefaultsFlag(GSUserDefaultFlagType type) { if (sharedDefaults == nil) { @@ -1984,3 +1846,25 @@ GSUserDefaultsFlag(GSUserDefaultFlagType type) return flags[type]; } +/* FIXME ... Slightly faster than + * [[NSUserDefaults standardUserDefaults] dictionaryRepresentation] + * but is it really worthwile? + */ +NSDictionary *GSPrivateDefaultLocale() +{ + NSDictionary *locale; + + if (classLock == nil) + { + [NSUserDefaults standardUserDefaults]; + } + [classLock lock]; + if (sharedDefaults == nil) + { + [NSUserDefaults standardUserDefaults]; + } + locale = [sharedDefaults dictionaryRepresentation]; + [classLock unlock]; + return locale; +} + diff --git a/Source/NSValue.m b/Source/NSValue.m index 4b559ef83..1e42866c6 100644 --- a/Source/NSValue.m +++ b/Source/NSValue.m @@ -20,7 +20,8 @@ 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., 51 Franklin Street, Fifth Floor, Boston, MA 02111 USA. + Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02111 USA. NSValue class reference $Date$ $Revision$ diff --git a/Source/NSValueTransformer.m b/Source/NSValueTransformer.m new file mode 100644 index 000000000..aa9a1ff78 --- /dev/null +++ b/Source/NSValueTransformer.m @@ -0,0 +1,235 @@ +/* Implementation for NSValueTransformer for GNUStep + Copyright (C) 2006 Free Software Foundation, Inc. + + Written Dr. H. Nikolaus Schaller + Created on Mon Mar 21 2005. + Updated (thread safety) by Richard Frith-Macdonald + + 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., 51 Franklin Street, Fifth Floor, + Boston, MA 02111 USA. + */ + +#import "Foundation/Foundation.h" +#import "GNUstepBase/GSLock.h" + +@interface NSNegateBooleanTransformer : NSValueTransformer +@end + +@interface NSIsNilTransformer : NSValueTransformer +@end + +@interface NSIsNotNilTransformer : NSValueTransformer +@end + +@interface NSUnarchiveFromDataTransformer : NSValueTransformer +@end + + +@implementation NSValueTransformer + +NSString * const NSNegateBooleanTransformerName + = @"NSNegateBooleanTransformerName"; +NSString * const NSIsNilTransformerName + = @"NSIsNilTransformerName"; +NSString * const NSIsNotNilTransformerName + = @"NSIsNotNilTransformerName"; +NSString * const NSUnarchiveFromDataTransformerName + = @"NSUnarchiveFromDataTransformerName"; + +// non-abstract methods + +static NSMutableDictionary *registry = nil; +static GSLazyLock *lock = nil; + ++ (void) initialize +{ + if (lock == nil) + { + NSValueTransformer *t; + + lock = [GSLazyLock new]; + registry = [[NSMutableDictionary alloc] init]; + + t = [NSNegateBooleanTransformer new]; + [self setValueTransformer: t + forName: NSNegateBooleanTransformerName]; + RELEASE(t); + + t = [NSIsNilTransformer new]; + [self setValueTransformer: t + forName: NSIsNilTransformerName]; + RELEASE(t); + + t = [NSIsNotNilTransformer new]; + [self setValueTransformer: t + forName: NSIsNotNilTransformerName]; + RELEASE(t); + + t = [NSUnarchiveFromDataTransformer new]; + [self setValueTransformer: t + forName: NSUnarchiveFromDataTransformerName]; + RELEASE(t); + } +} + ++ (void) setValueTransformer: (NSValueTransformer *)transformer + forName: (NSString *)name +{ + [lock lock]; + [registry setObject: transformer forKey: name]; + [lock unlock]; +} + ++ (NSValueTransformer *) valueTransformerForName: (NSString *)name +{ + NSValueTransformer *transformer; + + [lock lock]; + transformer = [registry objectForKey: name]; + RETAIN(transformer); + [lock unlock]; + return AUTORELEASE(transformer); +} + ++ (NSArray *) valueTransformerNames +{ + NSArray *names; + + [lock lock]; + names = [registry allKeys]; + [lock unlock]; + return names; +} + ++ (BOOL) allowsReverseTransformation +{ + [self subclassResponsibility: _cmd]; + return NO; +} + ++ (Class) transformedValueClass +{ + return [self subclassResponsibility: _cmd]; +} + +- (id) reverseTransformedValue: (id)value +{ + if ([[self class] allowsReverseTransformation] == NO) + { + [NSException raise: NSGenericException + format: @"[%@] is not reversible", + NSStringFromClass([self class])]; + } + return [self transformedValue: value]; +} + +- (id) transformedValue: (id)value +{ + return [self subclassResponsibility: _cmd]; +} + +@end + +// builtin transformers + +@implementation NSNegateBooleanTransformer + ++ (BOOL) allowsReverseTransformation +{ + return YES; +} + ++ (Class) transformedValueClass +{ + return [NSNumber class]; +} + +- (id) reverseTransformedValue: (id) value +{ + return [NSNumber numberWithBool: [value boolValue] ? NO : YES]; +} + +- (id) transformedValue: (id)value +{ + return [NSNumber numberWithBool: [value boolValue] ? NO : YES]; +} + +@end + +@implementation NSIsNilTransformer + ++ (BOOL) allowsReverseTransformation +{ + return NO; +} + ++ (Class) transformedValueClass +{ + return [NSNumber class]; +} + +- (id) transformedValue: (id)value +{ + return [NSNumber numberWithBool: (value == nil) ? YES : NO]; +} + +@end + +@implementation NSIsNotNilTransformer + ++ (BOOL) allowsReverseTransformation +{ + return NO; +} + ++ (Class) transformedValueClass +{ + return [NSNumber class]; +} + +- (id) transformedValue: (id)value +{ + return [NSNumber numberWithBool: (value != nil) ? YES : NO]; +} + +@end + +@implementation NSUnarchiveFromDataTransformer + ++ (BOOL) allowsReverseTransformation +{ + return YES; +} + ++ (Class) transformedValueClass +{ + return [NSData class]; +} + +- (id) reverseTransformedValue: (id)value +{ +// FIXME ... should we use a keyed archive? + return [NSKeyedArchiver archivedDataWithRootObject: value]; +} + +- (id) transformedValue: (id)value +{ +// FIXME ... should we use a keyed archive? + return [NSKeyedUnarchiver unarchiveObjectWithData: value]; +} + +@end diff --git a/Source/NSXMLParser.m b/Source/NSXMLParser.m index 0ade7f241..ec8309d19 100644 --- a/Source/NSXMLParser.m +++ b/Source/NSXMLParser.m @@ -18,11 +18,13 @@ 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., 51 Franklin Street, Fifth Floor, Boston, MA 02111 USA. + Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02111 USA. */ -#include +#include "config.h" +#include #include #include #include @@ -31,6 +33,10 @@ NSString* const NSXMLParserErrorDomain = @"NSXMLParserErrorDomain"; +#ifdef HAVE_LIBXML + +#include + @interface NSXMLSAXHandler : GSSAXHandler { @public @@ -434,6 +440,557 @@ NSString* const NSXMLParserErrorDomain = @"NSXMLParserErrorDomain"; @end +#else + +@implementation NSString (NSXMLParser) + +- (NSString *) _stringByExpandingXMLEntities +{ + NSMutableString *t=[NSMutableString stringWithString: self]; + [t replaceOccurrencesOfString: @"&" withString: @"&" options: 0 range: NSMakeRange(0, [t length])]; // must be first! + [t replaceOccurrencesOfString: @"<" withString: @"<" options: 0 range: NSMakeRange(0, [t length])]; + [t replaceOccurrencesOfString: @">" withString: @">" options: 0 range: NSMakeRange(0, [t length])]; + [t replaceOccurrencesOfString: @"\"" withString: @""" options: 0 range: NSMakeRange(0, [t length])]; + [t replaceOccurrencesOfString: @"'" withString: @"'" options: 0 range: NSMakeRange(0, [t length])]; + return t; +} + +@end + +static NSString *UTF8STR(const void *ptr, int len) +{ + NSString *s; + + s = [[NSString alloc] initWithBytes: ptr + length: len + encoding: NSUTF8StringEncoding]; + if (s == nil) + NSLog(@"could not convert to UTF8 string! bytes=%08x len=%d", ptr, len); + return AUTORELEASE(s); +} + +typedef struct NSXMLParserIvarsType +{ + NSMutableArray *tagPath; // hierarchy of tags + NSData *data; + NSError *error; + const unsigned char *cp; // character pointer + const unsigned char *cend; // end of data + int line; // current line (counts from 0) + int column; // current column (counts from 0) + BOOL abort; // abort parse loop + BOOL shouldProcessNamespaces; + BOOL shouldReportNamespacePrefixes; + BOOL shouldResolveExternalEntities; + BOOL acceptHTML; // be lazy with bad tag nesting +} NSXMLParserIvars; + +@implementation NSXMLParser + +#define this ((NSXMLParserIvars*)_parser) +#define _del ((id)_handler) + +- (void) abortParsing +{ + this->abort = YES; +} + +- (int) columnNumber +{ + return this->column; +} + +- (void) dealloc +{ + if (this != 0) + { + RELEASE(this->data); + RELEASE(this->error); + RELEASE(this->tagPath); + NSZoneFree([self zone], this); + } + [super dealloc]; +} + +- (id) delegate +{ + return _del; +} + +- (id) initWithContentsOfURL: (NSURL *)anURL +{ + return [self initWithData: [NSData dataWithContentsOfURL: anURL]]; +} + +- (id) initWithData: (NSData *)data +{ + if (data == nil) + { + DESTROY(self); + } + else + { + self = [super init]; + if (self) + { + _parser = NSZoneMalloc([self zone], sizeof(NSXMLParserIvars)); + memset(_parser, '\0', sizeof(NSXMLParserIvars)); + this->data = [data copy]; + this->tagPath = [[NSMutableArray alloc] init]; + this->cp = [this->data bytes]; + this->cend = this->cp + [this->data length]; + } + } + return self; +} + +- (int) lineNumber +{ + return this->line; +} + +- (void) setDelegate: (id)delegate +{ + _handler = delegate; +} + +- (NSError *) parserError +{ + return this->error; +} + +- (NSArray *) _tagPath +{ + return this->tagPath; +} + +#define cget() ((this->cp < this->cend)?(this->column++, *this->cp++): -1) + +- (BOOL) _parseError: (NSString *)message +{ +#if 0 + NSLog(@"XML parseError: %@", message); +#endif + NSError *err = nil; + + ASSIGN(this->error, err); + this->abort = YES; // break look + if ([_del respondsToSelector: @selector(parser:parseErrorOccurred:)]) + [_del parser: self parseErrorOccurred: this->error]; // pass error + return NO; +} + +- (void) _processTag: (NSString *)tag + isEnd: (BOOL)flag + withAttributes: (NSDictionary *)attributes +{ + if (this->acceptHTML) + tag = [tag lowercaseString]; // not case sensitive + if (!flag) + { + if ([tag isEqualToString: @"?xml"]) + { +#if 0 +NSLog(@"parserDidStartDocument: "); +#endif + if ([_del respondsToSelector: @selector(parserDidStartDocument:)]) + [_del parserDidStartDocument: self]; + return; + } + if ([tag hasPrefix: @"?"]) + { +#if 0 +NSLog(@"_processTag <%@%@ %@>", flag?@"/": @"", tag, attributes); +#endif + // parser: foundProcessingInstructionWithTarget: data: + return; + } + if ([tag isEqualToString: @"!DOCTYPE"]) + { +#if 0 +NSLog(@"_processTag <%@%@ %@>", flag?@"/": @"", tag, attributes); +#endif + return; + } + if ([tag isEqualToString: @"!ENTITY"]) + { +#if 0 +NSLog(@"_processTag <%@%@ %@>", flag?@"/": @"", tag, attributes); +#endif + return; + } + if ([tag isEqualToString: @"!CDATA"]) + { + // pass through as NSData + // parser: foundCDATA: +#if 0 +NSLog(@"_processTag <%@%@ %@>", flag?@"/": @"", tag, attributes); +#endif + return; + } + [this->tagPath addObject: tag]; // push on stack + if ([_del respondsToSelector: + @selector(parser:didStartElement:namespaceURI:qualifiedName:attributes:)]) + [_del parser: self + didStartElement: tag + namespaceURI: nil + qualifiedName: nil + attributes: attributes]; + } + else + { +// closing tag + if (this->acceptHTML) + { + // lazily close any missing tags on stack + while ([this->tagPath count] > 0 + && ![[this->tagPath lastObject] isEqualToString: tag]) + { + if ([_del respondsToSelector: + @selector(parser:didEndElement:namespaceURI:qualifiedName:)]) + [_del parser: self + didEndElement: [this->tagPath lastObject] + namespaceURI: nil + qualifiedName: nil]; + [this->tagPath removeLastObject]; // pop from stack + } + if ([this->tagPath count] == 0) + return; // ignore closing tag without matching open... + } + else if (![[this->tagPath lastObject] isEqualToString: tag]) + { + [self _parseError: [NSString stringWithFormat: + @"tag nesting error ( expected, found)", + [this->tagPath lastObject], tag]]; + return; + } + if ([_del respondsToSelector: + @selector(parser:didEndElement:namespaceURI:qualifiedName:)]) + [_del parser: self + didEndElement: tag + namespaceURI: nil + qualifiedName: nil]; + [this->tagPath removeLastObject]; // pop from stack + } +} + +- (NSString *) _entity +{ +// parse &xxx; sequence + int c; + const unsigned char *ep = this->cp; // should be position behind & + int len; + unsigned int val; + NSString *entity; + + do { + c = cget(); + } while (c != EOF && c != '<' && c != ';'); + + if (c != ';') + return nil; // invalid sequence - end of file or missing ; before next tag + len = this->cp - ep - 1; + if (*ep == '#') + { +// &#ddd; or &#xhh; + // !!! ep+1 is not 0-terminated - but by ;!! + if (sscanf((char *)ep+1, "x%x;", &val)) + return [NSString stringWithFormat: @"%C", val]; // &#xhh; hex value + else if (sscanf((char *)ep+1, "%d;", &val)) + return [NSString stringWithFormat: @"%C", val]; // &ddd; decimal value + } + else + { +// the five predefined entities + if (len == 3 && strncmp((char *)ep, "amp", len) == 0) + return @"&"; + if (len == 2 && strncmp((char *)ep, "lt", len) == 0) + return @"<"; + if (len == 2 && strncmp((char *)ep, "gt", len) == 0) + return @">"; + if (len == 4 && strncmp((char *)ep, "quot", len) == 0) + return @"\""; + if (len == 4 && strncmp((char *)ep, "apos", len) == 0) + return @"'"; + } + entity = UTF8STR(ep, len); +#if 1 + NSLog(@"NSXMLParser: unrecognized entity: &%@;", entity); +#endif +// entity=[entitiesTable objectForKey: entity]; // look up string in entity translation table + if (!entity) + entity=@"&??;"; // unknown entity + return entity; +} + +- (NSString *) _qarg +{ +// get argument (might be quoted) + const unsigned char *ap = --this->cp; // argument start pointer + int c = cget(); // refetch first character + +#if 0 + NSLog(@"_qarg: %02x %c", c, isprint(c)?c: ' '); +#endif + if (c == '\"') + { +// quoted argument + do { + c = cget(); + if (c == EOF) + return nil; // unterminated! + } while (c != '\"'); + return UTF8STR(ap + 1, this->cp - ap - 2); + } + if (c == '\'') + { +// apostrophed argument + do { + c = cget(); + if (c == EOF) + return nil; // unterminated! + } while (c != '\''); + return UTF8STR(ap + 1, this->cp - ap - 2); + } + if (!this->acceptHTML) + ; // strict XML requires quoting (?) + while (!isspace(c) && c != '>' && c != '/' && c != '?' && c != '=' &&c != EOF) + c = cget(); + this->cp--; // go back to terminating character + return UTF8STR(ap, this->cp - ap); +} + +- (BOOL) parse +{ +// read XML (or HTML) file + const unsigned char *vp = this->cp; // value pointer + int c; + + if (!this->acceptHTML + && (this->cend - this->cp < 6 + || strncmp((char *)this->cp, " preamble"]; + } + c = cget(); // get first character + while (!this->abort) + { +// parse next element +#if 0 + NSLog(@"_nextelement %02x %c", c, isprint(c)?c: ' '); +#endif + switch(c) + { + case '\r': + this->column = 0; + break; + case '\n': + this->line++; + this->column = 0; + case EOF: + case '<': + case '&': + { +// push out any characters that have been collected so far + if (this->cp - vp > 1) + { + // check for whitespace only - might set/reset a flag to indicate so + if ([_del respondsToSelector: @selector(parser: foundCharacters: )]) + [_del parser: self foundCharacters: UTF8STR(vp, this->cp - vp - 1)]; + vp = this->cp; + } + } + } + switch(c) + { + default: + c = cget(); // just collect until we push out (again) + continue; + case EOF: // end of file + { + if ([this->tagPath count] != 0) + { + if (!this->acceptHTML) + return [self _parseError: @"unexpected end of file"]; // strict XML nesting error + while ([this->tagPath count] > 0) + { +// lazily close all open tags + if ([_del respondsToSelector: @selector(parser: didEndElement: namespaceURI: qualifiedName: )]) + [_del parser: self didEndElement: [this->tagPath lastObject] namespaceURI: nil qualifiedName: nil]; + [this->tagPath removeLastObject]; // pop from stack + } + } +#if 0 + NSLog(@"parserDidEndDocument: "); +#endif + + if ([_del respondsToSelector: @selector(parserDidEndDocument: )]) + [_del parserDidEndDocument: self]; + return YES; + } + case '&': + { +// escape entity begins + NSString *entity=[self _entity]; + if (!entity) + return [self _parseError: @"empty entity name"]; + if ([_del respondsToSelector: @selector(parser: foundCharacters: )]) + [_del parser: self foundCharacters: entity]; + vp = this->cp; // next value sequence starts here + c = cget(); // first character behind ; + continue; + } + case '<': + { +// tag begins + NSString *tag; + NSMutableDictionary *parameters; + NSString *arg; + const unsigned char *tp = this->cp; // tag pointer + if (this->cp < this->cend-3 && strncmp((char *)this->cp, "!--", 3) == 0) + { +// start of comment skip all characters until "-->" + this->cp+=3; + while (this->cp < this->cend-3 && strncmp((char *)this->cp, "-->", 3) != 0) + this->cp++; // search + // if _del responds to parser: foundComment: + // convert to string (tp+4 ... cp) + this->cp+=3; // might go beyond cend but does not care + vp = this->cp; // value might continue + c = cget(); // get first character behind comment + continue; + } + c = cget(); // get first character of tag + if (c == '/') + c = cget(); // closing tag should process this tag in a special way so that e.g. is read as a single tag! + // to do this properly, we need a notion of comments and quoted string constants... + } + while (!isspace(c) && c != '>' && (c != '/') && (c != '?')) + c = cget(); // scan tag until we find a delimiting character + if (*tp == '/') + tag = UTF8STR(tp + 1, this->cp - tp - 2); // don't include / and delimiting character + else + tag = UTF8STR(tp, this->cp - tp - 1); // don't include delimiting character +#if 0 + NSLog(@"tag=%@ - %02x %c", tag, c, isprint(c)?c: ' '); +#endif + parameters=[NSMutableDictionary dictionaryWithCapacity: 5]; + while (c != EOF) + { +// collect arguments + if (c == '/' && *tp != '/') + { +// appears to be a /> + c = cget(); + if (c != '>') + return [self _parseError: @""]; + [self _processTag: tag isEnd: NO withAttributes: parameters]; // opening tag + [self _processTag: tag isEnd: YES withAttributes: nil]; // closing tag + break; // done + } + if (c == '?' && *tp == '?') + { +// appears to be a ?> + c = cget(); + if (c != '>') + return [self _parseError: @""]; + // process + [self _processTag: tag isEnd: NO withAttributes: parameters]; // single + break; // done + } + while (isspace(c)) // this->should also allow for line break and tab + c = cget(); + if (c == '>') + { + [self _processTag: tag isEnd: (*tp=='/') withAttributes: parameters]; // handle tag + break; + } + arg=[self _qarg]; // get next argument (eats up to /, ?, >, =, space) +#if 0 + NSLog(@"arg=%@", arg); +#endif + if (!this->acceptHTML && [arg length] == 0) + return [self _parseError: @"empty attribute name"]; + c = cget(); // get delimiting character + if (c == '=') + { +// explicit assignment + c = cget(); // skip = + [parameters setObject: [self _qarg] forKey: arg]; + c = cget(); // get character behind qarg value + } + else // implicit + [parameters setObject: @"" forKey: arg]; + } + vp = this->cp; // prepare for next value + c = cget(); // skip > and fetch next character + } + } + } + return [self _parseError: @"this->aborted"]; // this->aborted +} + +- (BOOL) acceptsHTML +{ + return this->acceptHTML; +} + +- (BOOL) shouldProcessNamespaces +{ + return this->shouldProcessNamespaces; +} + +- (BOOL) shouldReportNamespacePrefixes +{ + return this->shouldReportNamespacePrefixes; +} + +- (BOOL) shouldResolveExternalEntities +{ + return this->shouldResolveExternalEntities; +} + +- (void) setShouldProcessNamespaces: (BOOL)aFlag +{ + this->shouldProcessNamespaces = aFlag; +} + +- (void) setShouldReportNamespacePrefixes: (BOOL)aFlag +{ + this->shouldReportNamespacePrefixes = aFlag; +} + +- (void) setShouldResolveExternalEntities: (BOOL)aFlag +{ + this->shouldProcessNamespaces = aFlag; +} + +- (void) _setAcceptHTML: (BOOL) flag +{ + this->acceptHTML = flag; +} + +- (NSString *) publicID +{ + return [self notImplemented: _cmd]; +} + +- (NSString *) systemID +{ + return [self notImplemented: _cmd]; +} + +@end + +#endif + @implementation NSObject (NSXMLParserDelegateEventAdditions) - (NSData*) parser: (NSXMLParser*)aParser resolveExternalEntityName: (NSString*)aName diff --git a/Source/NSZone.m b/Source/NSZone.m index 1a96cc1c0..ad79f6aaa 100644 --- a/Source/NSZone.m +++ b/Source/NSZone.m @@ -19,7 +19,8 @@ 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., 51 Franklin Street, Fifth Floor, Boston, MA 02111 USA. + Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02111 USA. NSZone class reference $Date$ $Revision$ @@ -1702,12 +1703,12 @@ NSCreateZone (size_t start, size_t gran, BOOL canFree) newZone = (NSZone*)zone; } - [gnustep_global_lock lock]; - newZone->next = zone_list; - zone_list = newZone; - [gnustep_global_lock unlock]; + [gnustep_global_lock lock]; + newZone->next = zone_list; + zone_list = newZone; + [gnustep_global_lock unlock]; - return newZone; + return newZone; } /** diff --git a/Source/callframe.m b/Source/callframe.m index dece3d5e5..6aead1bf2 100644 --- a/Source/callframe.m +++ b/Source/callframe.m @@ -28,6 +28,7 @@ #include "callframe.h" #include "Foundation/NSException.h" #include "Foundation/NSData.h" +#include "Foundation/NSDebug.h" #include "GSInvocation.h" #if defined(ALPHA) || (defined(MIPS) && (_MIPS_SIM == _ABIN32)) @@ -235,6 +236,8 @@ callframe_do_call (DOContext *ctxt, id object; /* The selector for the message we're sending to the TARGET. */ SEL selector; + /* The OBJECT's Method(_t) pointer for the SELECTOR. */ + GSMethod meth; /* The OBJECT's implementation of the SELECTOR. */ IMP method_implementation; /* Type qualifier flags; see . */ @@ -276,25 +279,34 @@ callframe_do_call (DOContext *ctxt, as the ENCODED_TYPES string, but it will have different register and stack locations if the ENCODED_TYPES came from a machine of a different architecture. */ -#if NeXT_RUNTIME - { - Method m; - m = class_getInstanceMethod(object->isa, selector); - if (!m) - abort(); - type = m->method_types; - } -#elif 0 - { - Method_t m; - m = class_get_instance_method (object->class_pointer, - selector); - NSCParameterAssert (m); - type = m->method_types; - } -#else - type = sel_get_type (selector); -#endif /* NeXT_runtime */ + if (GSObjCIsClass(object)) + { + meth = GSGetMethod(object, selector, NO, YES); + } + else if (GSObjCIsInstance(object)) + { + meth = GSGetMethod(GSObjCClass(object), selector, YES, YES); + } + else + { + [NSException raise: NSInvalidArgumentException + format: @"decoded object %p is invalid", object]; + } + + if (meth != 0) + { + type = meth->method_types; + } + else + { + NSDebugLog(@"Local object <%p %s> doesn't implement: %s directly. " + @"Will search for arbitrary signature.", + object, + GSNameFromClass(GSObjCIsClass(object) + ? object : GSObjCClass(object)), + GSNameFromSelector(selector)); + type = GSTypesFromSelector(selector); + } /* Make sure we successfully got the method type, and that its types match the ENCODED_TYPES. */ diff --git a/Source/cifframe.m b/Source/cifframe.m index d17b3d1ef..35679105a 100644 --- a/Source/cifframe.m +++ b/Source/cifframe.m @@ -28,6 +28,7 @@ #include "cifframe.h" #include "Foundation/NSException.h" #include "Foundation/NSData.h" +#include "Foundation/NSDebug.h" #include "GSInvocation.h" #if defined(ALPHA) || (defined(MIPS) && (_MIPS_SIM == _ABIN32)) @@ -632,6 +633,8 @@ cifframe_do_call (DOContext *ctxt, id object; /* The selector for the message we're sending to the TARGET. */ SEL selector; + /* The OBJECT's Method(_t) pointer for the SELECTOR. */ + GSMethod meth; /* The OBJECT's implementation of the SELECTOR. */ IMP method_implementation; /* Type qualifier flags; see . */ @@ -673,25 +676,34 @@ cifframe_do_call (DOContext *ctxt, as the ENCODED_TYPES string, but it will have different register and stack locations if the ENCODED_TYPES came from a machine of a different architecture. */ -#if NeXT_RUNTIME - { - Method m; - m = class_getInstanceMethod(object->isa, selector); - if (!m) - abort(); - type = m->method_types; - } -#elif 0 - { - Method_t m; - m = class_get_instance_method (object->class_pointer, - selector); - NSCParameterAssert (m); - type = m->method_types; - } -#else - type = sel_get_type (selector); -#endif /* NeXT_runtime */ + if (GSObjCIsClass(object)) + { + meth = GSGetMethod(object, selector, NO, YES); + } + else if (GSObjCIsInstance(object)) + { + meth = GSGetMethod(GSObjCClass(object), selector, YES, YES); + } + else + { + [NSException raise: NSInvalidArgumentException + format: @"decoded object %p is invalid", object]; + } + + if (meth != 0) + { + type = meth->method_types; + } + else + { + NSDebugLog(@"Local object <%p %s> doesn't implement: %s directly. " + @"Will search for arbitrary signature.", + object, + GSNameFromClass(GSObjCIsClass(object) + ? object : GSObjCClass(object)), + GSNameFromSelector(selector)); + type = GSTypesFromSelector(selector); + } /* Make sure we successfully got the method type, and that its types match the ENCODED_TYPES. */ diff --git a/Source/externs.m b/Source/externs.m index fd4fdec20..9f5174993 100644 --- a/Source/externs.m +++ b/Source/externs.m @@ -18,13 +18,13 @@ 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., 51 Franklin Street, Fifth Floor, Boston, MA 02111 USA. + Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02111 USA. */ #include "config.h" #include "Foundation/NSString.h" - #include "Foundation/NSArray.h" #include "Foundation/NSException.h" @@ -72,11 +72,6 @@ NSString *NSThreadWillExitNotification = @"NSThreadWillExitNotification"; /* * Port Notifications */ -NSString *PortBecameInvalidNotification = @"PortBecameInvalidNotification"; - -NSString *InPortClientBecameInvalidNotification = @"InPortClientBecameInvalidNotification"; - -NSString *InPortAcceptedClientNotification = @"InPortAcceptedClientNotification"; NSString *NSPortDidBecomeInvalidNotification = @"NSPortDidBecomeInvalidNotification"; @@ -121,11 +116,6 @@ NSString *NSShowNonLocalizedStrings = @"NSShowNonLocalizedStrings"; NSString *NSLoadedClasses = @"NSLoadedClasses"; -/* Stream */ -NSString *StreamException = @"StreamException"; - - - /* Standard domains */ NSString *NSArgumentDomain = @"NSArgumentDomain"; @@ -240,7 +230,7 @@ NSString *NSClassDescriptionNeededForClassNotification = @"NSClassDescriptionNee */ void -GSBuildStrings() +GSPrivateBuildStrings() { static Class NSStringClass = 0; @@ -258,8 +248,6 @@ GSBuildStrings() [NSStringClass performSelector: @selector(initialize)]; GS_REPLACE_CONSTANT_STRING(GSNetworkNotificationCenterType); - GS_REPLACE_CONSTANT_STRING(InPortAcceptedClientNotification); - GS_REPLACE_CONSTANT_STRING(InPortClientBecameInvalidNotification); GS_REPLACE_CONSTANT_STRING(NSAMPMDesignation); GS_REPLACE_CONSTANT_STRING(NSArgumentDomain); GS_REPLACE_CONSTANT_STRING(NSBundleDidLoadNotification); @@ -322,8 +310,6 @@ GSBuildStrings() GS_REPLACE_CONSTANT_STRING(NSWeekDayNameArray); GS_REPLACE_CONSTANT_STRING(NSWillBecomeMultiThreadedNotification); GS_REPLACE_CONSTANT_STRING(NSYearMonthWeekDesignations); - GS_REPLACE_CONSTANT_STRING(PortBecameInvalidNotification); - GS_REPLACE_CONSTANT_STRING(StreamException); } } diff --git a/Source/libgnustep-base-entry.m b/Source/libgnustep-base-entry.m index f6178c35b..93b970a19 100644 --- a/Source/libgnustep-base-entry.m +++ b/Source/libgnustep-base-entry.m @@ -18,7 +18,8 @@ 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., 51 Franklin Street, Fifth Floor, Boston, MA 02111 USA. + Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02111 USA. */ #include "config.h" diff --git a/Source/mframe.m b/Source/mframe.m index 00c708639..108ec4054 100644 --- a/Source/mframe.m +++ b/Source/mframe.m @@ -18,8 +18,8 @@ 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., 51 Franklin Street, Fifth Floor, Boston, - MA 02111 USA. + Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02111 USA. */ /* These functions can be used for dissecting and making method calls @@ -38,6 +38,7 @@ #include "Foundation/NSObjCRuntime.h" #include "Foundation/NSData.h" #include "Foundation/NSException.h" +#include "Foundation/NSDebug.h" #include #include #include @@ -801,6 +802,8 @@ mframe_do_call (DOContext *ctxt, id object; /* The selector for the message we're sending to the TARGET. */ SEL selector; + /* The OBJECT's Method(_t) pointer for the SELECTOR. */ + GSMethod meth; /* The OBJECT's implementation of the SELECTOR. */ IMP method_implementation; /* The number bytes for holding arguments passed on the stack. */ @@ -865,25 +868,34 @@ mframe_do_call (DOContext *ctxt, as the ENCODED_TYPES string, but it will have different register and stack locations if the ENCODED_TYPES came from a machine of a different architecture. */ -#if NeXT_RUNTIME - { - Method m; - m = class_getInstanceMethod(object->isa, selector); - if (!m) - abort(); - type = m->method_types; - } -#elif 0 - { - Method_t m; - m = class_get_instance_method (object->class_pointer, - selector); - NSCParameterAssert (m); - type = m->method_types; - } -#else - type = sel_get_type (selector); -#endif /* NeXT_runtime */ + if (GSObjCIsClass(object)) + { + meth = GSGetMethod(object, selector, NO, YES); + } + else if (GSObjCIsInstance(object)) + { + meth = GSGetMethod(GSObjCClass(object), selector, YES, YES); + } + else + { + [NSException raise: NSInvalidArgumentException + format: @"decoded object %p is invalid", object]; + } + + if (meth != 0) + { + type = meth->method_types; + } + else + { + NSDebugLog(@"Local object <%p %s> doesn't implement: %s directly. " + @"Will search for arbitrary signature.", + object, + GSNameFromClass(GSObjCIsClass(object) + ? object : GSObjCClass(object)), + GSNameFromSelector(selector)); + type = GSTypesFromSelector(selector); + } /* Make sure we successfully got the method type, and that its types match the ENCODED_TYPES. */ diff --git a/Source/objc-gnu2next.m b/Source/objc-gnu2next.m index 08d322715..501c2f26c 100644 --- a/Source/objc-gnu2next.m +++ b/Source/objc-gnu2next.m @@ -19,7 +19,8 @@ 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., 51 Franklin Street, Fifth Floor, Boston, MA 02111 USA. + Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02111 USA. */ #include "config.h" diff --git a/Source/objc-load.h b/Source/objc-load.h index 0cc10f8fb..6713b3d8a 100644 --- a/Source/objc-load.h +++ b/Source/objc-load.h @@ -39,89 +39,4 @@ #define LINKER_GETSYMBOL 0 #endif -#if defined(__MINGW32__) -extern long objc_load_module( - const unichar *filename, - FILE *errorStream, - void (*loadCallback)(Class, struct objc_category *), - void **header, - const unichar *debugFilename); - -extern long objc_load_modules( - const unichar *files[], - FILE *errorStream, - void (*callback)(Class,struct objc_category *), - void **header, - const unichar *debugFilename); -#else -extern long objc_load_module( - const char *filename, - FILE *errorStream, - void (*loadCallback)(Class, struct objc_category *), - void **header, - const char *debugFilename); - -extern long objc_load_modules( - const char *files[], - FILE *errorStream, - void (*callback)(Class,struct objc_category *), - void **header, - const char *debugFilename); -#endif - -extern long objc_unload_module( - FILE *errorStream, - void (*unloadCallback)(Class, struct objc_category *)); - -extern long objc_unload_modules( - FILE *errorStream, - void (*unloadCallback)(Class, struct objc_category *)); - -/* - * objc_get_symbol_path() returns the path to the object file from - * which a certain class was loaded. - * - * If the class was loaded from a shared library, this returns the - * filesystem path to the shared library; if it was loaded from a - * dynamical object (such as a bundle or framework dynamically - * loaded), it returns the filesystem path to the object file; if the - * class was loaded from the main executable, it returns the - * filesystem path to the main executable path. - * - * This function is implemented by using the available features of - * the dynamic linker on the specific platform we are running on. - * - * On some platforms, the dynamic linker does not provide enough - * facilities to support the objc_get_symbol_path() function at all; - * in this case, objc_get_symbol_path() always returns nil. - * - * On my platform (a Debian GNU Linux), it seems the dynamic linker - * always returns the filesystem path that was used to load the - * module. So it returns the full filesystem path for shared libraries - * and bundles (which is very nice), but unfortunately it returns - * argv[0] (which might be something as horrible as './obj/test') - * for classes in the main executable. - * - * If theCategory argument is not NULL, objc_get_symbol_path() will return - * the filesystem path to the module from which the category theCategory - * of the class theClass was loaded. - * - * Currently, the function will return nil if any of the following - * conditions is satisfied: - * - the required functionality is not available on the platform we are - * running on; - * - memory allocation fails; - * - the symbol for that class/category could not be found. - * - * In general, if the function returns nil, it means something serious - * went wrong in the system preventing it from getting the symbol path. - * If your code is to be portable, you (unfortunately) have to be prepared - * to work around it in some way when this happens. - * - * It seems that this function has no corresponding function in the NeXT - * runtime ... as far as I know. - */ -extern -NSString *objc_get_symbol_path (Class theClass, Category *theCategory); - #endif /* __objc_load_h_INCLUDE */ diff --git a/Source/objc-load.m b/Source/objc-load.m index cae18be69..67bd9e050 100644 --- a/Source/objc-load.m +++ b/Source/objc-load.m @@ -52,21 +52,16 @@ #include "Foundation/NSDebug.h" #include "Foundation/NSException.h" +#include "GSPrivate.h" + /* include the interface to the dynamic linker */ #include "dynamic-load.h" -/* Declaration from NSBundle.m */ -#ifdef __MINGW32__ -const unichar *objc_executable_location (void); -#else -const char *objc_executable_location (void); -#endif - /* dynamic_loaded is YES if the dynamic loader was sucessfully initialized. */ static BOOL dynamic_loaded; /* Our current callback function */ -void (*_objc_load_load_callback)(Class, struct objc_category *) = 0; +static void (*_objc_load_load_callback)(Class, struct objc_category *) = 0; /* List of modules we have loaded (by handle) */ #ifndef NeXT_RUNTIME @@ -106,31 +101,27 @@ objc_check_undefineds(FILE *errorStream) static int objc_initialize_loading(FILE *errorStream) { + NSString *path; #ifdef __MINGW32__ - const unichar *path; + const unichar *fsPath; #else - const char *path; + const char *fsPath; #endif dynamic_loaded = NO; - path = objc_executable_location(); + path = GSPrivateExecutablePath(); -#ifdef __MINGW32__ NSDebugFLLog(@"NSBundle", - @"Debug (objc-load): initializing dynamic loader for %S", - path); -#else - NSDebugFLLog(@"NSBundle", - @"Debug (objc-load): initializing dynamic loader for %s", - path); -#endif + @"Debug (objc-load): initializing dynamic loader for %@", path); - if (__objc_dynamic_init(path)) + fsPath = [[path stringByDeletingLastPathComponent] fileSystemRepresentation]; + + if (__objc_dynamic_init(fsPath)) { if (errorStream) { __objc_dynamic_error(errorStream, - "Error (objc-load): Cannot initialize dynamic linker"); + "Error (objc-load): Cannot initialize dynamic linker"); } return 1; } @@ -155,25 +146,21 @@ objc_load_callback(Class class, struct objc_category * category) } #if defined(__MINGW32__) -long -objc_load_module (const unichar *filename, - FILE *errorStream, - void (*loadCallback)(Class, struct objc_category *), - void **header, - const unichar *debugFilename) +#define FSCHAR unichar #else -long -objc_load_module (const char *filename, - FILE *errorStream, - void (*loadCallback)(Class, struct objc_category *), - void **header, - const char *debugFilename) +#define FSCHAR char #endif + +long +GSPrivateLoadModule(NSString *filename, FILE *errorStream, + void (*loadCallback)(Class, struct objc_category *), + void **header, NSString *debugFilename) { #ifdef NeXT_RUNTIME int errcode; dynamic_loaded = YES; - return objc_loadModule(filename, loadCallback, &errcode); + return objc_loadModule([filename fileSystemRepresentation], + loadCallback, &errcode); #else typedef void (*void_fn)(); dl_handle_t handle; @@ -195,14 +182,9 @@ objc_load_module (const char *filename, _objc_load_callback = objc_load_callback; /* Link in the object file */ -#ifdef __MINGW32__ - NSDebugFLLog(@"NSBundle", - @"Debug (objc-load): Linking file %S\n", filename); -#else - NSDebugFLLog(@"NSBundle", - @"Debug (objc-load): Linking file %s\n", filename); -#endif - handle = __objc_dynamic_link(filename, 1, debugFilename); + NSDebugFLLog(@"NSBundle", @"Debug (objc-load): Linking file %@\n", filename); + handle = __objc_dynamic_link((FSCHAR*)[filename fileSystemRepresentation], + 1, (FSCHAR*)[debugFilename fileSystemRepresentation]); if (handle == 0) { if (errorStream) @@ -232,7 +214,7 @@ objc_load_module (const char *filename, if (errorStream) { fprintf(errorStream, - "Error (objc-load): Cannot load objects (no CTOR list)\n"); + "Error (objc-load): Cannot load objects (no CTOR list)\n"); } _objc_load_load_callback = 0; _objc_load_callback = 0; @@ -240,11 +222,11 @@ objc_load_module (const char *filename, } NSDebugFLLog(@"NSBundle", - @"Debug (objc-load): %d modules\n", (int)ctor_list[0]); + @"Debug (objc-load): %d modules\n", (int)ctor_list[0]); for (i = 1; ctor_list[i]; i++) { NSDebugFLLog(@"NSBundle", - @"Debug (objc-load): Invoking CTOR %p\n", ctor_list[i]); + @"Debug (objc-load): Invoking CTOR %p\n", ctor_list[i]); ctor_list[i](); } #endif /* not __ELF__ */ @@ -257,8 +239,8 @@ objc_load_module (const char *filename, } long -objc_unload_module(FILE *errorStream, - void (*unloadCallback)(Class, struct objc_category *)) +GSPrivateUnloadModule(FILE *errorStream, + void (*unloadCallback)(Class, struct objc_category *)) { if (!dynamic_loaded) { @@ -272,54 +254,14 @@ objc_unload_module(FILE *errorStream, return 0; } -#if defined(__MINGW32__) -long objc_load_modules(const unichar *files[],FILE *errorStream, - void (*callback)(Class,struct objc_category *), - void **header, - const unichar *debugFilename) -#else -long objc_load_modules(const char *files[],FILE *errorStream, - void (*callback)(Class,struct objc_category *), - void **header, - const char *debugFilename) -#endif -{ - while (*files) - { - if (objc_load_module(*files, errorStream, callback, - (void *)header, debugFilename)) - { - return 1; - } - files++; - } - return 0; -} - -long -objc_unload_modules(FILE *errorStream, - void (*unloadCallback)(Class, struct objc_category *)) -{ - if (!dynamic_loaded) - { - return 1; - } - - if (errorStream) - { - fprintf(errorStream, "Warning: unloading modules not implemented\n"); - } - - return 0; -} #ifdef __MINGW32__ NSString * -objc_get_symbol_path(Class theClass, Category *theCategory) +GSPrivateSymbolPath(Class theClass, Category *theCategory) { unichar buf[MAX_PATH]; MEMORY_BASIC_INFORMATION memInfo; - NSCAssert(!theCategory, @"objc_get_symbol_path doesn't support categories"); + NSCAssert(!theCategory, @"GSPrivateSymbolPath doesn't support categories"); VirtualQueryEx(GetCurrentProcess(), theClass, &memInfo, sizeof(memInfo)); if (GetModuleFileNameW(memInfo.AllocationBase, buf, sizeof(buf))) @@ -330,7 +272,7 @@ objc_get_symbol_path(Class theClass, Category *theCategory) } #else NSString * -objc_get_symbol_path(Class theClass, Category *theCategory) +GSPrivateSymbolPath(Class theClass, Category *theCategory) { const char *ret; char buf[125], *p = buf; @@ -385,7 +327,7 @@ objc_get_symbol_path(Class theClass, Category *theCategory) if (ret) { - return [NSString stringWithCString: ret]; + return [NSString stringWithUTF8String: ret]; } return nil; diff --git a/Source/preface.m b/Source/preface.m index 615871923..c37aedc59 100644 --- a/Source/preface.m +++ b/Source/preface.m @@ -18,15 +18,12 @@ 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., 51 Franklin Street, Fifth Floor, Boston, MA 02111 USA. + Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02111 USA. */ #include #include "GNUstepBase/preface.h" const char *gnustep_base_version = STRINGIFY (GNUSTEP_BASE_VERSION); -const char *o_gcc_version = STRINGIFY (GNUSTEP_BASE_GCC_VERSION); -#if NeXT_cc -const char *o_NeXT_cc_version = STRINGIFY (NX_CURRENT_COMPILER_RELEASE); -#endif /* NeXT_cc */ diff --git a/Source/unix/GSRunLoopCtxt.m b/Source/unix/GSRunLoopCtxt.m index 11ad51221..1c35cdd3f 100644 --- a/Source/unix/GSRunLoopCtxt.m +++ b/Source/unix/GSRunLoopCtxt.m @@ -9,13 +9,15 @@ #include "config.h" #include "GNUstepBase/preface.h" -#include "../GSRunLoopCtxt.h" -#include "../GSRunLoopWatcher.h" -#include "../GSPrivate.h" #include +#include +#include #include #include #include +#include "../GSRunLoopCtxt.h" +#include "../GSRunLoopWatcher.h" +#include "../GSPrivate.h" #ifdef HAVE_SYS_TYPES_H #include @@ -30,13 +32,11 @@ #include #endif -extern BOOL GSCheckTasks(); - #if GS_WITH_GC == 0 -SEL wRelSel; -SEL wRetSel; -IMP wRelImp; -IMP wRetImp; +static SEL wRelSel; +static SEL wRetSel; +static IMP wRelImp; +static IMP wRetImp; static void wRelease(NSMapTable* t, void* w) @@ -61,6 +61,17 @@ static const NSMapTableValueCallBacks WatcherMapValueCallBacks = #endif @implementation GSRunLoopCtxt + ++ (void) initialize +{ +#if GS_WITH_GC == 0 + wRelSel = @selector(release); + wRetSel = @selector(retain); + wRelImp = [[GSRunLoopWatcher class] instanceMethodForSelector: wRelSel]; + wRetImp = [[GSRunLoopWatcher class] instanceMethodForSelector: wRetSel]; +#endif +} + - (void) dealloc { RELEASE(mode); @@ -357,7 +368,7 @@ static void setPollfd(int fd, int event, GSRunLoopCtxt *ctxt) * we can service the queue. Similarly, if a task has completed, * we need to deliver its notifications. */ - if (GSCheckTasks() || GSNotifyMore() || immediate == YES) + if (GSPrivateCheckTasks() || GSPrivateNotifyMore() || immediate == YES) { milliseconds = 0; } @@ -395,7 +406,7 @@ static void setPollfd(int fd, int event, GSRunLoopCtxt *ctxt) { if (errno == EINTR) { - GSCheckTasks(); + GSPrivateCheckTasks(); poll_return = 0; } else if (errno == 0) @@ -408,8 +419,8 @@ static void setPollfd(int fd, int event, GSRunLoopCtxt *ctxt) /* Some exceptional condition happened. */ /* xxx We can do something with exception_fds, instead of aborting here. */ - NSLog (@"poll() error in -acceptInputForMode:beforeDate: '%s'", - GSLastErrorStr(errno)); + NSLog (@"poll() error in -acceptInputForMode:beforeDate: '%@'", + [NSError _last]); abort (); } } @@ -444,7 +455,7 @@ static void setPollfd(int fd, int event, GSRunLoopCtxt *ctxt) extra: watcher->data forMode: mode]; } - GSNotifyASAP(); + GSPrivateNotifyASAP(); } /* @@ -519,7 +530,7 @@ static void setPollfd(int fd, int event, GSRunLoopCtxt *ctxt) extra: (void*)(uintptr_t)fd forMode: mode]; } - GSNotifyASAP(); + GSPrivateNotifyASAP(); if (completed == YES) { break; // A nested poll has done the job. @@ -551,7 +562,7 @@ static void setPollfd(int fd, int event, GSRunLoopCtxt *ctxt) extra: (void*)(uintptr_t)fd forMode: mode]; } - GSNotifyASAP(); + GSPrivateNotifyASAP(); if (completed == YES) { break; // A nested poll has done the job. @@ -583,7 +594,7 @@ static void setPollfd(int fd, int event, GSRunLoopCtxt *ctxt) extra: (void*)(uintptr_t)fd forMode: mode]; } - GSNotifyASAP(); + GSPrivateNotifyASAP(); if (completed == YES) { break; // A nested poll has done the job. @@ -751,7 +762,7 @@ static void setPollfd(int fd, int event, GSRunLoopCtxt *ctxt) * we can service the queue. Similarly, if a task has completed, * we need to deliver its notifications. */ - if (GSCheckTasks() || GSNotifyMore() || immediate == YES) + if (GSPrivateCheckTasks() || GSPrivateNotifyMore() || immediate == YES) { timeout.tv_sec = 0; timeout.tv_usec = 0; @@ -776,7 +787,7 @@ static void setPollfd(int fd, int event, GSRunLoopCtxt *ctxt) { if (errno == EINTR) { - GSCheckTasks(); + GSPrivateCheckTasks(); select_return = 0; } else if (errno == 0) @@ -789,8 +800,8 @@ static void setPollfd(int fd, int event, GSRunLoopCtxt *ctxt) /* Some exceptional condition happened. */ /* xxx We can do something with exception_fds, instead of aborting here. */ - NSLog (@"select() error in -acceptInputForMode:beforeDate: '%s'", - GSLastErrorStr(errno)); + NSLog (@"select() error in -acceptInputForMode:beforeDate: '%@'", + [NSError _last]); abort (); } } @@ -825,7 +836,7 @@ static void setPollfd(int fd, int event, GSRunLoopCtxt *ctxt) extra: watcher->data forMode: mode]; } - GSNotifyASAP(); + GSPrivateNotifyASAP(); } /* @@ -886,7 +897,7 @@ static void setPollfd(int fd, int event, GSRunLoopCtxt *ctxt) extra: watcher->data forMode: mode]; } - GSNotifyASAP(); + GSPrivateNotifyASAP(); if (completed == YES) { break; @@ -918,7 +929,7 @@ static void setPollfd(int fd, int event, GSRunLoopCtxt *ctxt) extra: watcher->data forMode: mode]; } - GSNotifyASAP(); + GSPrivateNotifyASAP(); if (completed == YES) { break; @@ -950,7 +961,7 @@ static void setPollfd(int fd, int event, GSRunLoopCtxt *ctxt) extra: watcher->data forMode: mode]; } - GSNotifyASAP(); + GSPrivateNotifyASAP(); if (completed == YES) { break; diff --git a/Source/unix/NSStream.m b/Source/unix/NSStream.m index 13f6f060f..92f6867ec 100644 --- a/Source/unix/NSStream.m +++ b/Source/unix/NSStream.m @@ -292,8 +292,10 @@ static void setNonblocking(int fd) - (void) dealloc { if ([self _isOpened]) - [self close]; - RELEASE(_path); + { + [self close]; + } + DESTROY(_path); [super dealloc]; } @@ -321,9 +323,15 @@ static void setNonblocking(int fd) readLen = read((intptr_t)_loopID, buffer, len); if (readLen < 0 && errno != EAGAIN && errno != EINTR) - [self _recordError]; + { + [self _recordError]; + readLen = -1; + } else if (readLen == 0) - [self _setStatus: NSStreamStatusAtEnd]; + { + [self _setStatus: NSStreamStatusAtEnd]; + [self _sendEvent: NSStreamEventEndEncountered]; + } return readLen; } @@ -405,7 +413,7 @@ static void setNonblocking(int fd) - (void) setSibling: (GSOutputStream*)sibling { - ASSIGN(_sibling, sibling); + _sibling = sibling; } - (void) setPassive: (BOOL)passive @@ -427,8 +435,11 @@ static void setNonblocking(int fd) - (void) dealloc { if ([self _isOpened]) - [self close]; - RELEASE(_sibling); + { + [self close]; + } + [(GSSocketOutputStream*)_sibling setSibling: nil]; + _sibling = nil; [super dealloc]; } @@ -518,9 +529,15 @@ static void setNonblocking(int fd) readLen = read((intptr_t)_loopID, buffer, len); if (readLen < 0 && errno != EAGAIN && errno != EINTR) - [self _recordError]; + { + [self _recordError]; + readLen = -1; + } else if (readLen == 0) - [self _setStatus: NSStreamStatusAtEnd]; + { + [self _setStatus: NSStreamStatusAtEnd]; + [self _sendEvent: NSStreamEventEndEncountered]; + } return readLen; } @@ -707,7 +724,9 @@ static void setNonblocking(int fd) - (void) dealloc { if ([self _isOpened]) - [self close]; + { + [self close]; + } RELEASE(_path); [super dealloc]; } @@ -818,7 +837,7 @@ static void setNonblocking(int fd) - (void) setSibling: (GSInputStream*)sibling { - ASSIGN(_sibling, sibling); + _sibling = sibling; } - (void) setPassive: (BOOL)passive @@ -839,8 +858,11 @@ static void setNonblocking(int fd) - (void) dealloc { if ([self _isOpened]) - [self close]; - RELEASE(_sibling); + { + [self close]; + } + [(GSSocketInputStream*)_sibling setSibling: nil]; + _sibling = nil; [super dealloc]; } @@ -1413,7 +1435,9 @@ static void setNonblocking(int fd) - (void) dealloc { if ([self _isOpened]) - [self close]; + { + [self close]; + } [super dealloc]; } diff --git a/Source/win32/GSFileHandleWin32.m b/Source/win32/GSFileHandleWin32.m index 8d153db76..03e99148e 100644 --- a/Source/win32/GSFileHandleWin32.m +++ b/Source/win32/GSFileHandleWin32.m @@ -18,7 +18,8 @@ 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., 51 Franklin Street, Fifth Floor, Boston, MA 02111 USA. + Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02111 USA. */ #define _FILE_OFFSET_BITS 64 @@ -792,7 +793,7 @@ NSString * const GSSOCKSRecvAddr = @"GSSOCKSRecvAddr"; if ((net = socket(AF_INET, SOCK_STREAM, PF_UNSPEC)) == INVALID_SOCKET) { - NSLog(@"unable to create socket - %s", GSLastErrorStr(errno)); + NSLog(@"unable to create socket - %@", [NSError _last]); RELEASE(self); return nil; } @@ -806,8 +807,8 @@ NSString * const GSSOCKSRecvAddr = @"GSSOCKSRecvAddr"; { if (bind(net, (struct sockaddr *)&lsin, sizeof(lsin)) == SOCKET_ERROR) { - NSLog(@"unable to bind to port %s:%d - %s", inet_ntoa(lsin.sin_addr), - GSSwapBigI16ToHost(sin.sin_port), GSLastErrorStr(errno)); + NSLog(@"unable to bind to port %s:%d - %@", inet_ntoa(lsin.sin_addr), + GSSwapBigI16ToHost(sin.sin_port), [NSError _last]); (void) closesocket(net); RELEASE(self); return nil; @@ -825,9 +826,9 @@ NSString * const GSSOCKSRecvAddr = @"GSSOCKSRecvAddr"; { if (WSAGetLastError() != WSAEWOULDBLOCK) { - NSLog(@"unable to make connection to %s:%d - %s", + NSLog(@"unable to make connection to %s:%d - %@", inet_ntoa(sin.sin_addr), - GSSwapBigI16ToHost(sin.sin_port), GSLastErrorStr(errno)); + GSSwapBigI16ToHost(sin.sin_port), [NSError _last]); RELEASE(self); return nil; } @@ -891,7 +892,7 @@ NSString * const GSSOCKSRecvAddr = @"GSSOCKSRecvAddr"; if ((net = socket(AF_INET, SOCK_STREAM, PF_UNSPEC)) == INVALID_SOCKET) { - NSLog(@"unable to create socket - %s", GSLastErrorStr(errno)); + NSLog(@"unable to create socket - %@", [NSError _last]); RELEASE(self); return nil; } @@ -908,8 +909,8 @@ NSString * const GSSOCKSRecvAddr = @"GSSOCKSRecvAddr"; if (bind(net, (struct sockaddr *)&sin, sizeof(sin)) == SOCKET_ERROR) { - NSLog(@"unable to bind to port %s:%d - %s", inet_ntoa(sin.sin_addr), - GSSwapBigI16ToHost(sin.sin_port), GSLastErrorStr(errno)); + NSLog(@"unable to bind to port %s:%d - %@", inet_ntoa(sin.sin_addr), + GSSwapBigI16ToHost(sin.sin_port), [NSError _last]); (void) closesocket(net); RELEASE(self); return nil; @@ -917,7 +918,7 @@ NSString * const GSSOCKSRecvAddr = @"GSSOCKSRecvAddr"; if (listen(net, 256) == SOCKET_ERROR) { - NSLog(@"unable to listen on port - %s", GSLastErrorStr(errno)); + NSLog(@"unable to listen on port - %@", [NSError _last]); (void) closesocket(net); RELEASE(self); return nil; @@ -925,7 +926,7 @@ NSString * const GSSOCKSRecvAddr = @"GSSOCKSRecvAddr"; if (getsockname(net, (struct sockaddr*)&sin, &size) == SOCKET_ERROR) { - NSLog(@"unable to get socket name - %s", GSLastErrorStr(errno)); + NSLog(@"unable to get socket name - %@", [NSError _last]); (void) closesocket(net); RELEASE(self); return nil; @@ -1092,8 +1093,8 @@ NSString * const GSSOCKSRecvAddr = @"GSSOCKSRecvAddr"; if (_fstat(desc, &sbuf) != 0) { - NSLog(@"unable to get status of descriptor %d - %s", - desc, GSLastErrorStr(errno)); + NSLog(@"unable to get status of descriptor %d - %@", + desc, [NSError _last]); } else { @@ -1293,8 +1294,8 @@ NSString * const GSSOCKSRecvAddr = @"GSSOCKSRecvAddr"; if (len < 0) { [NSException raise: NSFileHandleOperationException - format: @"unable to read from descriptor - %s", - GSLastErrorStr(errno)]; + format: @"unable to read from descriptor - %@", + [NSError _last]]; } return d; } @@ -1318,8 +1319,8 @@ NSString * const GSSOCKSRecvAddr = @"GSSOCKSRecvAddr"; if (len < 0) { [NSException raise: NSFileHandleOperationException - format: @"unable to read from descriptor - %s", - GSLastErrorStr(errno)]; + format: @"unable to read from descriptor - %@", + [NSError _last]]; } return d; } @@ -1344,8 +1345,8 @@ NSString * const GSSOCKSRecvAddr = @"GSSOCKSRecvAddr"; if (got < 0) { [NSException raise: NSFileHandleOperationException - format: @"unable to read from descriptor - %s", - GSLastErrorStr(errno)]; + format: @"unable to read from descriptor - %@", + [NSError _last]]; } [d setLength: got]; } @@ -1367,8 +1368,8 @@ NSString * const GSSOCKSRecvAddr = @"GSSOCKSRecvAddr"; else if (got < 0) { [NSException raise: NSFileHandleOperationException - format: @"unable to read from descriptor - %s", - GSLastErrorStr(errno)]; + format: @"unable to read from descriptor - %@", + [NSError _last]]; } } while (len > 0 && got > 0); @@ -1414,8 +1415,8 @@ NSString * const GSSOCKSRecvAddr = @"GSSOCKSRecvAddr"; if (rval < 0) { [NSException raise: NSFileHandleOperationException - format: @"unable to write to descriptor - %s", - GSLastErrorStr(errno)]; + format: @"unable to write to descriptor - %@", + [NSError _last]]; } } @@ -1520,8 +1521,8 @@ NSString * const GSSOCKSRecvAddr = @"GSSOCKSRecvAddr"; if (result < 0) { [NSException raise: NSFileHandleOperationException - format: @"failed to move to offset in file - %s", - GSLastErrorStr(errno)]; + format: @"failed to move to offset in file - %@", + [NSError _last]]; } return (unsigned long long)result; } @@ -1544,8 +1545,8 @@ NSString * const GSSOCKSRecvAddr = @"GSSOCKSRecvAddr"; if (result < 0) { [NSException raise: NSFileHandleOperationException - format: @"failed to move to offset in file - %s", - GSLastErrorStr(errno)]; + format: @"failed to move to offset in file - %@", + [NSError _last]]; } return (unsigned long long)result; } @@ -1568,8 +1569,8 @@ NSString * const GSSOCKSRecvAddr = @"GSSOCKSRecvAddr"; if (result < 0) { [NSException raise: NSFileHandleOperationException - format: @"failed to move to offset in file - %s", - GSLastErrorStr(errno)]; + format: @"failed to move to offset in file - %@", + [NSError _last]]; } } @@ -1927,8 +1928,8 @@ NSString * const GSSOCKSRecvAddr = @"GSSOCKSRecvAddr"; { NSString *s; - s = [NSString stringWithFormat: @"Accept attempt failed - %s", - GSLastErrorStr(errno)]; + s = [NSString stringWithFormat: @"Accept attempt failed - %@", + [NSError _last]]; [readInfo setObject: s forKey: GSFileHandleNotificationError]; } else @@ -1996,8 +1997,8 @@ NSString * const GSSOCKSRecvAddr = @"GSSOCKSRecvAddr"; { NSString *s; - s = [NSString stringWithFormat: @"Read attempt failed - %s", - GSLastErrorStr(errno)]; + s = [NSString stringWithFormat: @"Read attempt failed - %@", + [NSError _last]]; [readInfo setObject: s forKey: GSFileHandleNotificationError]; [self postReadNotification]; } @@ -2005,8 +2006,8 @@ NSString * const GSSOCKSRecvAddr = @"GSSOCKSRecvAddr"; { NSString *s; - s = [NSString stringWithFormat: @"Read attempt failed - %s", - GSLastErrorStr(errno)]; + s = [NSString stringWithFormat: @"Read attempt failed - %@", + [NSError _last]]; [readInfo setObject: s forKey: GSFileHandleNotificationError]; [self postReadNotification]; } @@ -2038,15 +2039,25 @@ NSString * const GSSOCKSRecvAddr = @"GSSOCKSRecvAddr"; || operation == GSSOCKSConnect) { // Connection attempt completed. int result; + int rval; unsigned len = sizeof(result); - if (getsockopt((SOCKET)_get_osfhandle(descriptor), SOL_SOCKET, SO_ERROR, - (char*)&result, &len) == 0 && result != 0) + rval = getsockopt((SOCKET)_get_osfhandle(descriptor), SOL_SOCKET, + SO_ERROR, (char*)&result, &len); + if (rval != 0) { NSString *s; - s = [NSString stringWithFormat: @"Connect attempt failed - %s", - GSLastErrorStr(result)]; + s = [NSString stringWithFormat: @"Connect attempt failed - %@", + [NSError _last]]; + [info setObject: s forKey: GSFileHandleNotificationError]; + } + else if (result != 0) + { + NSString *s; + + s = [NSString stringWithFormat: @"Connect attempt failed - %@", + [NSError _systemError: result]]; [info setObject: s forKey: GSFileHandleNotificationError]; } else @@ -2080,7 +2091,7 @@ NSString * const GSSOCKSRecvAddr = @"GSSOCKSRecvAddr"; NSString *s; s = [NSString stringWithFormat: - @"Write attempt failed - %s", GSLastErrorStr(errno)]; + @"Write attempt failed - %@", [NSError _last]]; [info setObject: s forKey: GSFileHandleNotificationError]; [self postWriteNotification]; } @@ -2110,52 +2121,71 @@ NSString * const GSSOCKSRecvAddr = @"GSSOCKSRecvAddr"; { [self setNonBlocking: YES]; } - if (isSocket) { - if (WSAEnumNetworkEvents((SOCKET)_get_osfhandle(descriptor), - event, &ocurredEvents) == SOCKET_ERROR) + if (isSocket) { - NSLog(@"Error getting event type %d", WSAGetLastError()); - abort(); + if (WSAEnumNetworkEvents((SOCKET)_get_osfhandle(descriptor), + event, &ocurredEvents) == SOCKET_ERROR) + { + NSLog(@"Error getting event type %d", WSAGetLastError()); + abort(); + } + if (ocurredEvents.lNetworkEvents & FD_CONNECT) + { + NSDebugMLLog(@"NSFileHandle", @"Connect on %x", extra); + ocurredEvents.lNetworkEvents ^= FD_CONNECT; + [self receivedEventWrite]; + GSPrivateNotifyASAP(); + } + if (ocurredEvents.lNetworkEvents & FD_ACCEPT) + { + NSDebugMLLog(@"NSFileHandle", @"Accept on %x", extra); + ocurredEvents.lNetworkEvents ^= FD_ACCEPT; + [self receivedEventRead]; + GSPrivateNotifyASAP(); + } + if (ocurredEvents.lNetworkEvents & FD_WRITE) + { + NSDebugMLLog(@"NSFileHandle", @"Write on %x", extra); + ocurredEvents.lNetworkEvents ^= FD_WRITE; + [self receivedEventWrite]; + GSPrivateNotifyASAP(); + } + if (ocurredEvents.lNetworkEvents & FD_READ) + { + NSDebugMLLog(@"NSFileHandle", @"Read on %x", extra); + ocurredEvents.lNetworkEvents ^= FD_READ; + [self receivedEventRead]; + GSPrivateNotifyASAP(); + } + if (ocurredEvents.lNetworkEvents & FD_OOB) + { + NSDebugMLLog(@"NSFileHandle", @"OOB on %x", extra); + ocurredEvents.lNetworkEvents ^= FD_OOB; + [self receivedEventRead]; + GSPrivateNotifyASAP(); + } + if (ocurredEvents.lNetworkEvents & FD_CLOSE) + { + NSDebugMLLog(@"NSFileHandle", @"Close on %x", extra); + ocurredEvents.lNetworkEvents ^= FD_CLOSE; + if ([writeInfo count] > 0) + { + [self receivedEventWrite]; + } + else + { + [self receivedEventRead]; + } + GSPrivateNotifyASAP(); + } + if (ocurredEvents.lNetworkEvents) + { + NSLog(@"Event not get %d", ocurredEvents.lNetworkEvents); + abort(); + } } - if (ocurredEvents.lNetworkEvents & FD_CONNECT) + else { - NSDebugMLLog(@"NSFileHandle", @"Connect on %x", extra); - ocurredEvents.lNetworkEvents ^= FD_CONNECT; - [self receivedEventWrite]; - GSNotifyASAP(); - } - if (ocurredEvents.lNetworkEvents & FD_ACCEPT) - { - NSDebugMLLog(@"NSFileHandle", @"Accept on %x", extra); - ocurredEvents.lNetworkEvents ^= FD_ACCEPT; - [self receivedEventRead]; - GSNotifyASAP(); - } - if (ocurredEvents.lNetworkEvents & FD_WRITE) - { - NSDebugMLLog(@"NSFileHandle", @"Write on %x", extra); - ocurredEvents.lNetworkEvents ^= FD_WRITE; - [self receivedEventWrite]; - GSNotifyASAP(); - } - if (ocurredEvents.lNetworkEvents & FD_READ) - { - NSDebugMLLog(@"NSFileHandle", @"Read on %x", extra); - ocurredEvents.lNetworkEvents ^= FD_READ; - [self receivedEventRead]; - GSNotifyASAP(); - } - if (ocurredEvents.lNetworkEvents & FD_OOB) - { - NSDebugMLLog(@"NSFileHandle", @"OOB on %x", extra); - ocurredEvents.lNetworkEvents ^= FD_OOB; - [self receivedEventRead]; - GSNotifyASAP(); - } - if (ocurredEvents.lNetworkEvents & FD_CLOSE) - { - NSDebugMLLog(@"NSFileHandle", @"Close on %x", extra); - ocurredEvents.lNetworkEvents ^= FD_CLOSE; if ([writeInfo count] > 0) { [self receivedEventWrite]; @@ -2164,23 +2194,7 @@ NSString * const GSSOCKSRecvAddr = @"GSSOCKSRecvAddr"; { [self receivedEventRead]; } - GSNotifyASAP(); - } - if (ocurredEvents.lNetworkEvents) - { - NSLog(@"Event not get %d", ocurredEvents.lNetworkEvents); - abort(); - } - } else { - if ([writeInfo count] > 0) - { - [self receivedEventWrite]; - } - else - { - [self receivedEventRead]; - } - GSNotifyASAP(); + GSPrivateNotifyASAP(); } } @@ -2193,7 +2207,8 @@ NSString * const GSSOCKSRecvAddr = @"GSSOCKSRecvAddr"; - (void) setAddr: (struct sockaddr_in *)sin { - address = [[NSString alloc] initWithCString: (char*)inet_ntoa(sin->sin_addr)]; + address = [[NSString alloc] initWithUTF8String: + (char*)inet_ntoa(sin->sin_addr)]; service = [[NSString alloc] initWithFormat: @"%d", (int)GSSwapBigI16ToHost(sin->sin_port)]; protocol = @"tcp"; @@ -2239,8 +2254,8 @@ NSString * const GSSOCKSRecvAddr = @"GSSOCKSRecvAddr"; if (ioctlsocket((SOCKET)_get_osfhandle(descriptor), FIONBIO, &dummy) == SOCKET_ERROR) { - NSLog(@"unable to set non-blocking mode - %s", - GSLastErrorStr(errno)); + NSLog(@"unable to set non-blocking mode - %@", + [NSError _last]); } else isNonBlocking = flag; @@ -2251,8 +2266,7 @@ NSString * const GSSOCKSRecvAddr = @"GSSOCKSRecvAddr"; if (ioctlsocket((SOCKET)_get_osfhandle(descriptor), FIONBIO, &dummy) == SOCKET_ERROR) { - NSLog(@"unable to set blocking mode - %s", - GSLastErrorStr(errno)); + NSLog(@"unable to set blocking mode - %@", [NSError _last]); } else isNonBlocking = flag; @@ -2273,11 +2287,11 @@ NSString * const GSSOCKSRecvAddr = @"GSSOCKSRecvAddr"; if (getsockname(descriptor, (struct sockaddr*)&sin, &size) == SOCKET_ERROR) { - NSLog(@"unable to get socket name - %s", GSLastErrorStr(errno)); + NSLog(@"unable to get socket name - %@", [NSError _last]); } else { - str = [NSString stringWithCString: (char*)inet_ntoa(sin.sin_addr)]; + str = [NSString stringWithUTF8String: (char*)inet_ntoa(sin.sin_addr)]; } return str; } @@ -2290,7 +2304,7 @@ NSString * const GSSOCKSRecvAddr = @"GSSOCKSRecvAddr"; if (getsockname(descriptor, (struct sockaddr*)&sin, &size) == SOCKET_ERROR) { - NSLog(@"unable to get socket name - %s", GSLastErrorStr(errno)); + NSLog(@"unable to get socket name - %@", [NSError _last]); } else { diff --git a/Source/win32/GSRunLoopCtxt.m b/Source/win32/GSRunLoopCtxt.m index 0056115a9..0d268c3a7 100644 --- a/Source/win32/GSRunLoopCtxt.m +++ b/Source/win32/GSRunLoopCtxt.m @@ -9,21 +9,21 @@ #include "config.h" #include "GNUstepBase/preface.h" -#include "../GSRunLoopCtxt.h" -#include "../GSRunLoopWatcher.h" -#include "../GSPrivate.h" #include +#include +#include #include #include #include - -extern BOOL GSCheckTasks(); +#include "../GSRunLoopCtxt.h" +#include "../GSRunLoopWatcher.h" +#include "../GSPrivate.h" #if GS_WITH_GC == 0 -SEL wRelSel; -SEL wRetSel; -IMP wRelImp; -IMP wRetImp; +static SEL wRelSel; +static SEL wRetSel; +static IMP wRelImp; +static IMP wRetImp; static void wRelease(NSMapTable* t, void* w) @@ -48,6 +48,17 @@ static const NSMapTableValueCallBacks WatcherMapValueCallBacks = #endif @implementation GSRunLoopCtxt + ++ (void) initialize +{ +#if GS_WITH_GC == 0 + wRelSel = @selector(release); + wRetSel = @selector(retain); + wRelImp = [[GSRunLoopWatcher class] instanceMethodForSelector: wRelSel]; + wRetImp = [[GSRunLoopWatcher class] instanceMethodForSelector: wRetSel]; +#endif +} + - (void) dealloc { RELEASE(mode); @@ -364,7 +375,7 @@ static const NSMapTableValueCallBacks WatcherMapValueCallBacks = * we can service the queue. Similarly, if a task has completed, * we need to deliver its notifications. */ - if (GSCheckTasks() || GSNotifyMore() || immediate == YES) + if (GSPrivateCheckTasks() || GSPrivateNotifyMore() || immediate == YES) { wait_timeout = 0; } @@ -425,8 +436,7 @@ static const NSMapTableValueCallBacks WatcherMapValueCallBacks = BOOL found = NO; NSDebugMLLog(@"NSRunLoop", @"WaitForMultipleObjects() error in " - @"-acceptInputForMode:beforeDate: %s", - GSLastErrorStr(GetLastError())); + @"-acceptInputForMode:beforeDate: %@", [NSError _last]); /* * Check each handle in turn until either we find one which has an * event signalled, or we find the one which caused the original @@ -447,8 +457,7 @@ static const NSMapTableValueCallBacks WatcherMapValueCallBacks = if (found == NO) { NSLog(@"WaitForMultipleObjects() error in " - @"-acceptInputForMode:beforeDate: %s", - GSLastErrorStr(GetLastError())); + @"-acceptInputForMode:beforeDate: %@", [NSError _last]); abort (); } } @@ -484,7 +493,7 @@ static const NSMapTableValueCallBacks WatcherMapValueCallBacks = extra: watcher->data forMode: mode]; } - GSNotifyASAP(); + GSPrivateNotifyASAP(); } // if there are windows message @@ -536,7 +545,7 @@ static const NSMapTableValueCallBacks WatcherMapValueCallBacks = forMode: mode]; } - GSNotifyASAP(); + GSPrivateNotifyASAP(); completed = YES; return YES; diff --git a/Source/win32/NSMessagePortNameServerWin32.m b/Source/win32/NSMessagePortNameServerWin32.m index a1682d6a5..a7e13923b 100644 --- a/Source/win32/NSMessagePortNameServerWin32.m +++ b/Source/win32/NSMessagePortNameServerWin32.m @@ -27,6 +27,7 @@ #include "Foundation/NSAutoreleasePool.h" #include "Foundation/NSDebug.h" +#include "Foundation/NSError.h" #include "Foundation/NSException.h" #include "Foundation/NSLock.h" #include "Foundation/NSMapTable.h" @@ -39,6 +40,7 @@ #include "GNUstepBase/GSMime.h" +#include "../GSPrivate.h" #include "GSPortPrivate.h" #define UNISTR(X) \ @@ -155,16 +157,20 @@ static void clean_up_names(void) + (NSString *) _query: (NSString *)name { - NSString *n; - NSString *p; - unsigned char buf[25]; - DWORD len = 25; + NSString *mailslotName; + NSString *translatedName; + NSString *mailslotPath; + unsigned char buf[1024]; + unsigned char *ptr = buf; + DWORD max = 1024; + DWORD len = 1024; DWORD type; HANDLE h; int rc; - n = [[self class] _translate: name]; + translatedName = [[self class] _translate: name]; +#if 1 /* FIXME ... wierd hack. * It appears that RegQueryValueExW does not always read from the registry, * but will in fact return cached results (even if you close and re-open the @@ -186,29 +192,55 @@ static void clean_up_names(void) * port. */ OutputDebugStringW(L""); +#endif rc = RegQueryValueExW( key, - UNISTR(n), + UNISTR(translatedName), (LPDWORD)0, &type, - (LPBYTE)buf, + (LPBYTE)ptr, &len); + while (rc == ERROR_MORE_DATA) + { + if (ptr != buf) + { + objc_free(ptr); + } + max += 1024; + ptr = objc_malloc(max); + len = max; + rc = RegQueryValueExW( + key, + UNISTR(translatedName), + (LPDWORD)0, + &type, + (LPBYTE)ptr, + &len); + } if (rc != ERROR_SUCCESS) { + if (ptr != buf) + { + objc_free(ptr); + } return nil; } - n = [NSString stringWithUTF8String: buf]; + mailslotName = [NSString stringWithUTF8String: ptr]; + if (ptr != buf) + { + objc_free(ptr); + } /* - * See if we can open the mailslot ... if not, the query returned + * See if we can open the port mailslot ... if not, the query returned * an old name, and we can remove it. */ - p = [NSString stringWithFormat: - @"\\\\.\\mailslot\\GNUstep\\NSMessagePort\\%@", n]; + mailslotPath = [NSString stringWithFormat: + @"\\\\.\\mailslot\\GNUstep\\NSMessagePort\\%@", mailslotName]; h = CreateFileW( - UNISTR(p), + UNISTR(mailslotPath), GENERIC_WRITE, FILE_SHARE_READ|FILE_SHARE_WRITE, &security, @@ -217,13 +249,16 @@ OutputDebugStringW(L""); (HANDLE)0); if (h == INVALID_HANDLE_VALUE) { - RegDeleteValueW(key, UNISTR(n)); + NSDebugLLog(@"NSMessagePortNameServer", + @"Failed to open mailslot (%@) for write on port named %@ - %@", + mailslotPath, name, [NSError _last]); + //RegDeleteValueW(key, UNISTR(n)); return nil; } else { CloseHandle(h); // OK - return n; + return mailslotName; } } @@ -242,6 +277,11 @@ OutputDebugStringW(L""); return name; } +- (NSPort*) portForName: (NSString *)name +{ + return [self portForName: name onHost: @""]; +} + - (NSPort*) portForName: (NSString *)name onHost: (NSString *)host { @@ -250,10 +290,15 @@ OutputDebugStringW(L""); NSDebugLLog(@"NSMessagePortNameServer", @"portForName: %@ host: %@", name, host); - if ([host length] && ![host isEqual: @"*"]) + if ([host length] != 0) { - NSDebugLLog(@"NSMessagePortNameServer", @"non-local host"); - return nil; + [NSException raise: NSInvalidArgumentException + format: @"Attempt to contact a named host using a " + @"message port name server. This name server can only be used " + @"to contact processes owned by the same user on the local host " + @"(host name must be an empty string). To contact processes " + @"owned by other users or on other hosts you must use an instance " + @"of the NSSocketPortNameServer class."]; } n = [[self class] _query: name]; @@ -275,6 +320,7 @@ OutputDebugStringW(L""); NSMutableArray *a; NSString *n; int rc; + const unsigned char *str; NSDebugLLog(@"NSMessagePortNameServer", @"register %@ as %@\n", port, name); if ([port isKindOfClass: [NSMessagePort class]] == NO) @@ -292,14 +338,16 @@ OutputDebugStringW(L""); } n = [[self class] _translate: name]; + str = [[(NSMessagePort*)port name] UTF8String]; rc = RegSetValueExW( key, UNISTR(n), 0, REG_BINARY, - [[(NSMessagePort*)port name] UTF8String], - 25); + str, + strlen(str)+1); + NSDebugLLog(@"NSMessagePortNameServer", @"Set port '%s' for %@", str, n); if (rc == ERROR_SUCCESS) { rc = RegFlushKey(key); @@ -311,8 +359,8 @@ OutputDebugStringW(L""); } else { - NSLog(@"Failed to insert HKEY_CURRENT_USER\\%@\\%@ (%x) %s", - registry, n, rc, GSLastErrorStr(rc)); + NSLog(@"Failed to insert HKEY_CURRENT_USER\\%@\\%@ (%x) %@", + registry, n, rc, [NSError _last]); return NO; } diff --git a/Source/win32/NSMessagePortWin32.m b/Source/win32/NSMessagePortWin32.m index aada0bdda..33ace7cfe 100644 --- a/Source/win32/NSMessagePortWin32.m +++ b/Source/win32/NSMessagePortWin32.m @@ -26,6 +26,7 @@ #include "GNUstepBase/GSLock.h" #include "Foundation/NSArray.h" #include "Foundation/NSNotification.h" +#include "Foundation/NSError.h" #include "Foundation/NSException.h" #include "Foundation/NSRunLoop.h" #include "Foundation/NSByteOrder.h" @@ -43,6 +44,7 @@ #include "Foundation/NSFileManager.h" #include "Foundation/NSProcessInfo.h" +#include "../GSPrivate.h" #include "GSPortPrivate.h" #include @@ -160,6 +162,9 @@ static Class messagePortClass = 0; (HANDLE)0); if (this->wHandle == INVALID_HANDLE_VALUE) { + NSDebugMLLog(@"NSMessagePort", + @"unable to access mailslot '%@' for write - %@", + [self name], [NSError _last]); result = NO; } else @@ -203,10 +208,6 @@ static Class messagePortClass = 0; { p = [[self alloc] initWithName: name]; } - else - { - [p _setupSendPort]; - } M_UNLOCK(messagePortLock); return p; } @@ -332,8 +333,8 @@ static Class messagePortClass = 0; if (this->rHandle == INVALID_HANDLE_VALUE) { - NSLog(@"unable to create mailslot '%@' - %s", - this->name, GSLastErrorStr(errno)); + NSLog(@"unable to create mailslot '%@' - %@", + this->name, [NSError _last]); DESTROY(self); } else @@ -360,6 +361,7 @@ static Class messagePortClass = 0; - (id) initWithName: (NSString*)name { NSMessagePort *p; + BOOL found = NO; M_LOCK(messagePortLock); p = RETAIN((NSMessagePort*)NSMapGet(ports, (void*)name)); @@ -381,25 +383,32 @@ static Class messagePortClass = 0; this->rEvent = INVALID_HANDLE_VALUE; this->wHandle = INVALID_HANDLE_VALUE; this->wEvent = INVALID_HANDLE_VALUE; - - if ([self _setupSendPort] == NO) - { - NSLog(@"unable to access mailslot '%@' - %s", - this->name, GSLastErrorStr(errno)); - DESTROY(self); - } - else - { - NSMapInsert(ports, (void*)this->name, (void*)self); - NSDebugMLLog(@"NSMessagePort", @"Created speaking port: %@", self); - } } else { + found = YES; RELEASE(self); - [p _setupSendPort]; self = p; } + + /* This is a 'speaking' port ... set it up for write operation + * if necessary. + * NB. This must be done (to create the mailbox) before the port + * is added to the nameserver mapping ... or nother process might + * try to access the mailbox before it exists. + */ + if ([self _setupSendPort] == NO) + { + DESTROY(self); + } + + if (self != nil && found == NO) + { + /* This was newly created ... add to map so that it can be found. + */ + NSMapInsert(ports, (void*)[self name], (void*)self); + NSDebugMLLog(@"NSMessagePort", @"Created speaking port: %@", self); + } M_UNLOCK(messagePortLock); return self; } @@ -515,14 +524,14 @@ static Class messagePortClass = 0; } else { - NSLog(@"GetOverlappedResult failed ...%s", GSLastErrorStr(errno)); + NSLog(@"GetOverlappedResult failed ... %@", [NSError _last]); this->rState = RS_NONE; this->rLength = 0; } } else { - NSLog(@"GetOverlappedResult success ...%u", this->rSize); + NSLog(@"GetOverlappedResult success ... %u", this->rSize); this->rState = RS_NONE; this->rLength = 0; } @@ -537,8 +546,8 @@ static Class messagePortClass = 0; 0, 0) == 0) { - NSLog(@"unable to get info from mailslot '%@' - %s", - this->name, GSLastErrorStr(errno)); + NSLog(@"unable to get info from mailslot '%@' - %@", + this->name, [NSError _last]); [self invalidate]; return; } @@ -554,16 +563,15 @@ static Class messagePortClass = 0; &this->rSize, NULL) == 0) { - NSLog(@"unable to read from mailslot '%@' - %s", - this->name, GSLastErrorStr(errno)); + NSLog(@"unable to read from mailslot '%@' - %@", + this->name, [NSError _last]); [self invalidate]; return; } if (this->rSize != this->rWant) { - NSLog(@"only read %d of %d bytes from mailslot '%@' - %s", - this->rSize, this->rWant, this->name, - GSLastErrorStr(errno)); + NSLog(@"only read %d of %d bytes from mailslot '%@' - %@", + this->rSize, this->rWant, this->name, [NSError _last]); [self invalidate]; return; } @@ -757,8 +765,8 @@ static Class messagePortClass = 0; } else { - NSLog(@"unable to read from mailslot '%@' - %s", - this->name, GSLastErrorStr(errno)); + NSLog(@"unable to read from mailslot '%@' - %@", + this->name, [NSError _last]); [self invalidate]; } } @@ -812,7 +820,7 @@ static Class messagePortClass = 0; &this->wSize, TRUE) == 0) { - NSLog(@"GetOverlappedResult failed ...%s", GSLastErrorStr(errno)); + NSLog(@"GetOverlappedResult failed ... %@", [NSError _last]); } else { @@ -864,8 +872,8 @@ again: } else if ((errno = GetLastError()) != ERROR_IO_PENDING) { - NSLog(@"unable to write to mailslot '%@' - %s", - this->name, GSLastErrorStr(errno)); + NSLog(@"unable to write to mailslot '%@' - %@", + this->name, [NSError _last]); [self invalidate]; } else @@ -935,6 +943,28 @@ again: return sizeof(GSPortItemHeader) + sizeof(GSPortMsgHeader); } +- (void) release +{ + /* We lock the port table while checking, to prevent + * another thread from grabbing this port while we are + * checking it. + * If we are going to deallocate the object, we first remove + * it from the table so that no other thread will find it + * and try to use it while it is being deallocated. + */ + M_LOCK(messagePortLock); + if (NSDecrementExtraRefCountWasZero(self)) + { + NSMapRemove(ports, (void*)[self name]); + M_UNLOCK(messagePortLock); + [self dealloc]; + } + else + { + M_UNLOCK(messagePortLock); + } +} + - (BOOL) sendBeforeDate: (NSDate*)when msgid: (int)msgId components: (NSMutableArray*)components diff --git a/Source/win32/NSStreamWin32.m b/Source/win32/NSStreamWin32.m index 7730fb8ae..decab0391 100644 --- a/Source/win32/NSStreamWin32.m +++ b/Source/win32/NSStreamWin32.m @@ -270,7 +270,7 @@ static void setNonblocking(SOCKET fd) unsigned long dummy = 1; if (ioctlsocket(fd, FIONBIO, &dummy) == SOCKET_ERROR) - NSLog(@"unable to set non-blocking mode - %@", GSLastErrorStr(errno)); + NSLog(@"unable to set non-blocking mode - %@", [NSError _last]); } @implementation GSFileInputStream @@ -860,6 +860,7 @@ static void setNonblocking(SOCKET fd) else if (readLen == 0) { [self _setStatus: NSStreamStatusAtEnd]; + [self _sendEvent: NSStreamEventEndEncountered]; } else { @@ -1019,7 +1020,7 @@ static void setNonblocking(SOCKET fd) { _peerAddr.sin_family = AF_INET; _peerAddr.sin_port = htons(port); - _peerAddr.sin_addr.s_addr = inet_addr(addr_c); + _peerAddr.sin_addr.s_addr = addr_c ? inet_addr(addr_c) : INADDR_NONE; if (_peerAddr.sin_addr.s_addr == INADDR_NONE) // error { DESTROY(self); @@ -1758,7 +1759,7 @@ static void setNonblocking(SOCKET fd) { _peerAddr.sin_family = AF_INET; _peerAddr.sin_port = htons(port); - _peerAddr.sin_addr.s_addr = inet_addr(addr_c); + _peerAddr.sin_addr.s_addr = addr_c ? inet_addr(addr_c) : INADDR_NONE; if (_peerAddr.sin_addr.s_addr == INADDR_NONE) // error { DESTROY(self); @@ -1873,7 +1874,7 @@ static void setNonblocking(SOCKET fd) { [NSException raise: NSInternalInconsistencyException format: @"Unable to open named pipe '%@'... %@", - path, GSLastErrorStr(errno)]; + path, [NSError _last]]; } // the type of the stream does not matter, since we are only using the fd @@ -2366,7 +2367,7 @@ done: [super init]; _serverAddr.sin_family = AF_INET; _serverAddr.sin_port = htons(port); - _serverAddr.sin_addr.s_addr = inet_addr(addr_c); + _serverAddr.sin_addr.s_addr = addr_c ? inet_addr(addr_c) : INADDR_NONE; _sock = socket(AF_INET, SOCK_STREAM, 0); if (_serverAddr.sin_addr.s_addr == INADDR_NONE || _loopID < 0) // error { diff --git a/Source/win32/NSUserDefaultsWin32.m b/Source/win32/NSUserDefaultsWin32.m index 2c9d2d3d5..24688bf30 100644 --- a/Source/win32/NSUserDefaultsWin32.m +++ b/Source/win32/NSUserDefaultsWin32.m @@ -228,30 +228,35 @@ struct NSUserDefaultsWin32_DomainInfo id v; NSString *k; - switch (type) { - case REG_SZ: { - int datacharlen = datalen / 2; - if (datacharlen > 0 && data[datacharlen-1] == 0) - datacharlen--; + switch (type) + { + case REG_SZ: + { + int datacharlen = datalen / 2; + if (datacharlen > 0 && data[datacharlen-1] == 0) + datacharlen--; - v = [NSString stringWithCharacters:data length:datacharlen]; - } - break; - case REG_BINARY: { - v = [NSString stringWithCString: (char*)data - encoding: NSASCIIStringEncoding]; - } - break; - default: - NSLog(@"Bad registry type %d for '%S'", type, name); - v = 0; - } + v = [NSString stringWithCharacters: data + length: datacharlen]; + } + break; + case REG_BINARY: + { + v = [NSString stringWithCString: (char*)data + encoding: NSASCIIStringEncoding]; + } + break; + default: + NSLog(@"Bad registry type %d for '%S'", type, name); + v = 0; + } v = [v propertyList]; if (v) - { - k = [NSString stringWithCharacters: name length: namelen]; - [domainDict setObject: v forKey: k]; - } + { + k = [NSString stringWithCharacters: name + length: namelen]; + [domainDict setObject: v forKey: k]; + } } NS_HANDLER NSLog(@"Bad registry value for '%S'", name); @@ -319,30 +324,35 @@ struct NSUserDefaultsWin32_DomainInfo id v; NSString *k; - switch (type) { - case REG_SZ: { - int datacharlen = datalen / 2; - if (datacharlen > 0 && data[datacharlen-1] == 0) - datacharlen--; + switch (type) + { + case REG_SZ: + { + int datacharlen = datalen / 2; + if (datacharlen > 0 && data[datacharlen-1] == 0) + datacharlen--; - v = [NSString stringWithCharacters:data length:datacharlen]; - } - break; - case REG_BINARY: { - v = [NSString stringWithCString: (char*)data - encoding: NSASCIIStringEncoding]; - } - break; - default: - NSLog(@"Bad registry type %d for '%S'", type, name); - v = 0; - } + v = [NSString stringWithCharacters: data + length: datacharlen]; + } + break; + case REG_BINARY: + { + v = [NSString stringWithCString: (char*)data + encoding: NSASCIIStringEncoding]; + } + break; + default: + NSLog(@"Bad registry type %d for '%S'", type, name); + v = 0; + } v = [v propertyList]; if (v) - { - k = [NSString stringWithCharacters: name length: namelen]; - [domainDict setObject: v forKey: k]; - } + { + k = [NSString stringWithCharacters: name + length: namelen]; + [domainDict setObject: v forKey: k]; + } } NS_HANDLER NSLog(@"Bad registry value for '%S'", name); diff --git a/Testing/GNUmakefile b/Testing/GNUmakefile index a7fe0c634..47b711b23 100644 --- a/Testing/GNUmakefile +++ b/Testing/GNUmakefile @@ -22,7 +22,16 @@ # Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02111, USA. # +ifeq ($(GNUSTEP_MAKEFILES),) + GNUSTEP_MAKEFILES := $(shell gnustep-config --variable=GNUSTEP_MAKEFILES 2>/dev/null)$(warning computed GNUSTEP_MAKEFILES) +endif + +ifeq ($(GNUSTEP_MAKEFILES),) + $(error You need to set GNUSTEP_MAKEFILES before compiling!) +endif + GNUSTEP_LOCAL_ADDITIONAL_MAKEFILES=../base.make + include $(GNUSTEP_MAKEFILES)/common.make include ../Version diff --git a/Testing/README b/Testing/README index 772f8a8fb..622458e14 100644 --- a/Testing/README +++ b/Testing/README @@ -4,7 +4,7 @@ to do quick checks to make sure things are working. This is not a comprehensive test suite. Some tests don't say if they have passed or not. Some tests do not even output anything. Some tests never quit! -If you want to run a comprehensive testsuite. Install gnustep-guile -(ftp://ftp.gnustep.org/pub/gnustep/libs) and run the gnustep testsuite -(ftp://ftp.gnustep.org/pub/gnustep/tests). +If you want to run a comprehensive testsuite, run the gnustep testsuite +http://svn.gna.org/viewcvs/gnustep/tests/testsuite +(also ftp://ftp.gnustep.org/pub/gnustep/test). diff --git a/Testing/benchmark.m b/Testing/benchmark.m index 3957a4c96..052ee69ed 100755 --- a/Testing/benchmark.m +++ b/Testing/benchmark.m @@ -263,7 +263,7 @@ bench_array() { char buf1[100]; sprintf(buf1, "str%0d", i); - strings[i] = [stringClass stringWithCString: buf1]; + strings[i] = [stringClass stringWithUTF8String: buf1]; } printf("NSArray\n"); array = [NSMutableArray arrayWithCapacity: 16]; @@ -316,8 +316,8 @@ bench_dict() char buf1[100], buf2[100]; sprintf(buf1, "key%0d", i); sprintf(buf2, "val%0d", i); - keys[i] = [stringClass stringWithCString: buf1]; - vals[i] = [stringClass stringWithCString: buf2]; + keys[i] = [stringClass stringWithUTF8String: buf1]; + vals[i] = [stringClass stringWithUTF8String: buf2]; } printf("NSDictionary\n"); dict = [NSMutableDictionary dictionaryWithCapacity: 16]; @@ -487,7 +487,7 @@ bench_str() START_TIMER; for (i = 0; i < MAX_COUNT; i++) { - str = [stringClass stringWithCString: "hello world"]; + str = [stringClass stringWithUTF8String: "hello world"]; } END_TIMER; PRINT_TIMER("NSString (1 cstring:) \t\t"); diff --git a/Testing/call.m b/Testing/call.m index 7a587a16d..01df80206 100644 --- a/Testing/call.m +++ b/Testing/call.m @@ -72,11 +72,11 @@ GS_EXPORT NSString * const GSTelnetTextKey; if (i > 0 && ptr[i-1] == '\r') { - s = [NSString stringWithCString: ptr length: i-1]; + s = [NSString stringWithUTF8String: ptr length: i-1]; } else { - s = [NSString stringWithCString: ptr length: i]; + s = [NSString stringWithUTF8String: ptr length: i]; } len -= (i + 1); if (len > 0) diff --git a/Testing/exported-strings.m b/Testing/exported-strings.m index fd742191c..1d92e4255 100644 --- a/Testing/exported-strings.m +++ b/Testing/exported-strings.m @@ -31,7 +31,7 @@ #define MyAssert2(IDENT) do { \ NSCAssert2([IDENT isEqual: \ - [NSString stringWithCString: #IDENT]], \ + [NSString stringWithUTF8String: #IDENT]], \ @"Invalid value: %@ for: %s", \ IDENT, #IDENT); \ NSCAssert2([cache[i++] isEqual: IDENT], \ @@ -55,9 +55,6 @@ main() MyAssert1(NSWillBecomeMultiThreadedNotification); MyAssert1(NSThreadDidStartNotification); MyAssert1(NSThreadWillExitNotification); - // MyAssert1(PortBecameInvalidNotification); - // MyAssert1(InPortClientBecameInvalidNotification); - // MyAssert1(InPortAcceptedClientNotification); MyAssert1(NSPortDidBecomeInvalidNotification); MyAssert1(NSConnectionReplyMode); MyAssert1(NSBundleDidLoadNotification); @@ -118,9 +115,6 @@ main() MyAssert2(NSWillBecomeMultiThreadedNotification); MyAssert2(NSThreadDidStartNotification); MyAssert2(NSThreadWillExitNotification); - // MyAssert2(PortBecameInvalidNotification); - // MyAssert2(InPortClientBecameInvalidNotification); - // MyAssert2(InPortAcceptedClientNotification); MyAssert2(NSPortDidBecomeInvalidNotification); MyAssert2(NSConnectionReplyMode); MyAssert2(NSBundleDidLoadNotification); diff --git a/Testing/nsconnection_server.m b/Testing/nsconnection_server.m index ac3af5461..e4e04f778 100644 --- a/Testing/nsconnection_server.m +++ b/Testing/nsconnection_server.m @@ -522,7 +522,7 @@ int main(int argc, char *argv[], char **env) [c setRootObject: l]; if (optind < argc) - [c registerName: [NSString stringWithCString: argv[optind]]]; + [c registerName: [NSString stringWithUTF8String: argv[optind]]]; else [c registerName: @"test2server"]; diff --git a/Testing/nsprocessinfo.m b/Testing/nsprocessinfo.m index ff1c239c8..e3aeac72f 100644 --- a/Testing/nsprocessinfo.m +++ b/Testing/nsprocessinfo.m @@ -23,24 +23,25 @@ int main(int argc, char *argv[]) NSString* aKey; NSEnumerator* enumerator; - printf("Host name: %s\n",[[pi hostName] cString]); + printf("Host name: %s\n",[[pi hostName] UTF8String]); printf("Operating system: %d\n",[pi operatingSystem]); - printf("Operating system name: %s\n",[[pi operatingSystemName] cString]); - printf("Process Name: %s\n",[[pi processName] cString]); - printf("Globally Unique String: %s\n",[[pi globallyUniqueString] cString]); + printf("Operating system name: %s\n",[[pi operatingSystemName] UTF8String]); + printf("Operating system version: %s\n",[[pi operatingSystemVersionString] UTF8String]); + printf("Process Name: %s\n",[[pi processName] UTF8String]); + printf("Globally Unique String: %s\n",[[pi globallyUniqueString] UTF8String]); printf("\nProcess arguments\n"); printf("%d argument(s)\n", [[pi arguments] count]); enumerator = [[pi arguments] objectEnumerator]; while ((aString = [enumerator nextObject])) - printf("-->%s\n",[aString cString]); + printf("-->%s\n",[aString UTF8String]); printf("\nProcess environment\n"); printf("%d environment variables(s)\n", [[pi environment] count]); enumerator = [[pi environment] keyEnumerator]; while ((aKey = [enumerator nextObject])) - printf("++>%s=%s\n",[aKey cString],[[[pi environment] - objectForKey:aKey] cString]); + printf("++>%s=%s\n",[aKey UTF8String],[[[pi environment] + objectForKey:aKey] UTF8String]); [arp release]; exit(0); diff --git a/Testing/tcpport-client.m b/Testing/tcpport-client.m index fbab00093..6188eb420 100644 --- a/Testing/tcpport-client.m +++ b/Testing/tcpport-client.m @@ -33,7 +33,7 @@ int main (int argc, char *argv[]) if (argc > 1) out_port = [TcpOutPort newForSendingToRegisteredName: - [NSString stringWithCString: argv[1]] + [NSString stringWithUTF8String: argv[1]] onHost: @"localhost"]; else out_port = [TcpOutPort newForSendingToRegisteredName: @"tcpport-test" diff --git a/Testing/tcpport-server.m b/Testing/tcpport-server.m deleted file mode 100644 index 988d9b1b7..000000000 --- a/Testing/tcpport-server.m +++ /dev/null @@ -1,128 +0,0 @@ -/* Test/example program for the base library - - Copyright (C) 2005 Free Software Foundation, Inc. - - Copying and distribution of this file, with or without modification, - are permitted in any medium without royalty provided the copyright - notice and this notice are preserved. - - This file is part of the GNUstep Base Library. -*/ -#include -#include -#include -#include -#include - -@interface Dummy: NSObject -+ (id) announce_new_connection: notification; -+ (id) announce_broken_connection: notification; -@end - -@implementation Dummy - -+ announce_new_connection: notification -{ - id in_port = [notification object]; - id out_port = [notification userInfo]; - NSLog (@"{%@}\n\tconnected to\n\t{%@}\n", - [out_port description], [in_port description]); - NSLog (@"Now servicing %d connection(s).\n", - [in_port numberOfConnectedOutPorts]); - return nil; -} - -+ announce_broken_connection: notification -{ - id in_port = [notification object]; - id out_port = [notification userInfo]; - NSLog (@"{%@}\n\tdisconnected from\n\t{%@}\n", - [out_port description], [in_port description]); - NSLog (@"Now servicing %d connection(s).\n", - [in_port numberOfConnectedOutPorts]); - return nil; -} -@end - -static id port = nil; - -id handle_incoming_packet (TcpInPacket *packet) -{ - static unsigned message_count = 0; - id reply_port; - - message_count++; - fprintf (stdout, "received >"); - fwrite ([packet streamBuffer] + [packet streamBufferPrefix], - [packet streamEofPosition], 1, stdout); - fprintf (stdout, "<\n"); - reply_port = [packet replyOutPort]; - [packet release]; - - packet = [[TcpOutPacket alloc] initForSendingWithCapacity: 100 - replyInPort: port]; - [packet writeFormat: @"Your's was my message number %d", - message_count]; - [reply_port sendPacket: packet timeout:10.0]; - [packet release]; - return nil; -} - -int main (int argc, char *argv[]) -{ - if (argc > 1) - port = [TcpInPort newForReceivingFromRegisteredName: - [NSString stringWithCString: argv[1]]]; - else - port = [TcpInPort newForReceivingFromRegisteredName: @"tcpport-test"]; - - [[NSNotificationCenter defaultCenter] - addObserver: [Dummy class] - selector: @selector(announce_broken_connection:) - name: InPortClientBecameInvalidNotification - object: port]; - [[NSNotificationCenter defaultCenter] - addObserver: [Dummy class] - selector: @selector(announce_new_connection:) - name: InPortAcceptedClientNotification - object: port]; - - printf ("Waiting for connections.\n"); - -#if 1 - [port setReceivedPacketInvocation: - [[[ObjectFunctionInvocation alloc] - initWithObjectFunction: handle_incoming_packet] - autorelease]]; - [[NSRunLoop currentRunLoop] addPort: port - forMode: NSDefaultRunLoopMode]; - [[NSRunLoop currentRunLoop] run]; -#else - { - id packet; - unsigned message_count = 0; - id reply_port; - - while ((packet = [port receivePacketWithTimeout: -1])) - { - message_count++; - fprintf (stdout, "received >"); - fwrite ([packet streamBuffer] + [packet streamBufferPrefix], - [packet streamEofPosition], 1, stdout); - fprintf (stdout, "<\n"); - reply_port = [packet replyPort]; - [packet release]; - - packet = [[TcpPacket alloc] initForSendingWithCapacity: 100 - replyPort: port]; - [packet writeFormat: @"Your's was my message number %d", - message_count]; - [reply_port sendPacket: packet timeout: 20.0]; - [packet release]; - } - } -#endif - fprintf (stdout, "Timed out. Exiting.\n"); - - exit (0); -} diff --git a/Testing/thread-except.m b/Testing/thread-except.m index 4c6884e47..4020d1659 100644 --- a/Testing/thread-except.m +++ b/Testing/thread-except.m @@ -25,6 +25,7 @@ #define MAX_ITER 10000.0 /* Max number of iterations. */ FILE *file; +int counter; @interface SingleThread : NSObject { @@ -51,19 +52,17 @@ FILE *file; NS_DURING n = 1+(int)((MAX_ITER*rand())/(RAND_MAX+1.0)); - fflush(stdout); for (i = 0; i < n; i++) { fprintf(file, "%d ", i); fflush(file); } - fflush(stdout); [NSException raise: @"Some exception" format: @"thread %d", ident]; NS_HANDLER - printf("%s: %s for thread %d\n", [[localException name] cString], - [[localException reason] cString], ident); + NSLog(@"%@ for thread %d\n", localException, ident); NS_ENDHANDLER DESTROY(pool); + counter--; [NSThread exit]; } @@ -80,6 +79,9 @@ int main() printf("but the exception associated with each thread must match.\n"); file = fopen("/dev/null", "w"); srand(10); + + counter = N; + for (i = 0; i < N; i++) threads[i] = [[SingleThread alloc] initWithInt: i]; NS_DURING @@ -88,13 +90,14 @@ int main() toTarget: threads[i] withObject: nil]; // Hopefully this will end after all the other threads end. - for (i = 0; i < N*MAX_ITER; i++) + for (i = 0; i < N*MAX_ITER && counter > 0; i++) { + [NSThread sleepUntilDate: [NSDate dateWithTimeIntervalSinceNow: 1.0]]; fprintf(file, "%d", i); fflush(file); } NS_HANDLER - printf("There's a runaway exception! Something is wrong!\n"); + fprintf(stderr, "There's a runaway exception! Something is wrong!\n"); NS_ENDHANDLER fclose(file); DESTROY(pool); diff --git a/Testing/thread.m b/Testing/thread.m index ba1c0087f..f0c93ea7e 100644 --- a/Testing/thread.m +++ b/Testing/thread.m @@ -11,9 +11,11 @@ #include NSLock *lock = nil; +unsigned retainReleaseThreads = 0; @interface XX : NSObject - (void) fire; +- (void) retainRelease: (id)obj; - (void) setup; @end @@ -22,6 +24,21 @@ NSLock *lock = nil; { NSLog(@"Got here"); } +- (void) retainRelease: (id)obj +{ + unsigned i; + + NSLog(@"Start retain/releases in thread %@", [NSThread currentThread]); + for (i = 0; i < 1000000; i++) + { + [obj retain]; + [obj release]; + } + [lock lock]; + retainReleaseThreads++; + [lock unlock]; + NSLog(@"Done %d retain/releases in thread %@", i, [NSThread currentThread]); +} - (void) setup { CREATE_AUTORELEASE_POOL(arp); @@ -42,6 +59,7 @@ NSLock *lock = nil; withObject: nil waitUntilDone: YES]; NSLog(@"Done perform with wait."); + [lock unlock]; } else { @@ -55,13 +73,31 @@ NSLock *lock = nil; int main(int argc, char **argv, char **env) { CREATE_AUTORELEASE_POOL(arp); + NSObject *o = [NSObject new]; + XX *x = [XX new]; NSLog(@"Start in main"); lock = [NSLock new]; [lock lock]; + [NSThread detachNewThreadSelector: @selector(retainRelease:) + toTarget: x + withObject: o]; + [NSThread detachNewThreadSelector: @selector(retainRelease:) + toTarget: x + withObject: o]; + [NSThread detachNewThreadSelector: @selector(retainRelease:) + toTarget: x + withObject: o]; + [NSThread detachNewThreadSelector: @selector(retainRelease:) + toTarget: x + withObject: o]; + [NSThread detachNewThreadSelector: @selector(retainRelease:) + toTarget: x + withObject: o]; + [NSThread detachNewThreadSelector: @selector(setup) - toTarget: [XX new] + toTarget: x withObject: nil]; NSLog(@"Waiting to give thread time to start"); [NSThread sleepUntilDate: [NSDate dateWithTimeIntervalSinceNow: 1.0]]; @@ -73,6 +109,16 @@ int main(int argc, char **argv, char **env) NSLog(@"Done main thread"); + while (retainReleaseThreads < 5) + { + NSLog(@"Waiting for all 5 retainRelease threads to complete (%d)", + retainReleaseThreads); + [NSThread sleepUntilDate: [NSDate dateWithTimeIntervalSinceNow: 1.0]]; + } + if ([o retainCount] != 1) + { + NSLog(@"ERROR ... retain count is %d, expected 1", [o retainCount]); + } DESTROY(arp); return 0; } diff --git a/Tools/AGSOutput.m b/Tools/AGSOutput.m index 832153668..eb04b9ee7 100644 --- a/Tools/AGSOutput.m +++ b/Tools/AGSOutput.m @@ -2334,8 +2334,8 @@ static BOOL snuggleStart(NSString *t) [str appendString: @"\n"]; [str appendString: @"\n"]; + [str appendString: @"\"-//GNUstep//DTD gsdoc 1.0.3//EN\" "]; + [str appendString: @"\"http://www.gnustep.org/gsdoc-1_0_3.xml\">\n"]; [str appendString: @" - +