Index: configure.ac ================================================================== --- configure.ac +++ configure.ac @@ -1,21 +1,27 @@ AC_INIT(objfw, 0.1, js@webkeks.org) AC_CONFIG_SRCDIR(src) AC_CANONICAL_HOST -AC_CANONICAL_TARGET AC_PROG_CC AC_PROG_OBJC AC_PROG_CPP AC_PROG_LN_S AC_PROG_EGREP CFLAGS="$CFLAGS -Wall" OBJCFLAGS="$OBJCFLAGS -Wall -fobjc-exceptions" +OBJCFLAGS="$OBJCFLAGS -fconstant-string-class=OFConstString" LIBS="$LIBS -lobjc" +AX_CHECK_COMPILER_FLAGS(-pipe, [ + CFLAGS="$CFLAGS -pipe" + OBJCFLAGS="$OBJCFLAGS -pipe"]) +AX_CHECK_COMPILER_FLAGS(-fno-constant-cfstrings, + [OBJCFLAGS="$OBJCFLAGS -fno-constant-cfstrings"]) + AC_DEFINE(OF_CONFIG_H, 1, [Define so that we know we got our config.h]) BUILDSYS_LIB AC_DEFINE_UNQUOTED(PLUGIN_SUFFIX, "$PLUGIN_SUFFIX", [Suffix for plugins]) @@ -131,13 +137,10 @@ test x"$ac_cv_have_ipv6" = x"yes" && \ AC_DEFINE(HAVE_IPV6, 1, "Whether we have IPv6 support") AC_CHECK_HEADERS(sys/mman.h) -test x"$GCC" = x"yes" && CFLAGS="$CFLAGS -Werror -pipe -g" -test x"$GCC" = x"yes" && OBJCFLAGS="$OBJCFLAGS -Werror -pipe -g" - if test x"$cross_compiling" = x"yes"; then case "$target" in *-*-mingw*) AC_PATH_PROG(WINE, wine) ADDED m4/ax_check_compiler_flags.m4 Index: m4/ax_check_compiler_flags.m4 ================================================================== --- m4/ax_check_compiler_flags.m4 +++ m4/ax_check_compiler_flags.m4 @@ -0,0 +1,78 @@ +# =========================================================================== +# http://autoconf-archive.cryp.to/ax_check_compiler_flags.html +# =========================================================================== +# +# SYNOPSIS +# +# AX_CHECK_COMPILER_FLAGS(FLAGS, [ACTION-SUCCESS], [ACTION-FAILURE]) +# +# DESCRIPTION +# +# Check whether the given compiler FLAGS work with the current language's +# compiler, or whether they give an error. (Warnings, however, are +# ignored.) +# +# ACTION-SUCCESS/ACTION-FAILURE are shell commands to execute on +# success/failure. +# +# LAST MODIFICATION +# +# 2008-04-12 +# +# COPYLEFT +# +# Copyright (c) 2008 Steven G. Johnson +# Copyright (c) 2008 Matteo Frigo +# +# This program is free software: you can redistribute it and/or modify it +# under the terms of the GNU General Public License as published by the +# Free Software Foundation, either version 3 of the License, or (at your +# option) any later version. +# +# This program 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 General +# Public License for more details. +# +# You should have received a copy of the GNU General Public License along +# with this program. If not, see . +# +# As a special exception, the respective Autoconf Macro's copyright owner +# gives unlimited permission to copy, distribute and modify the configure +# scripts that are the output of Autoconf when processing the Macro. You +# need not follow the terms of the GNU General Public License when using +# or distributing such scripts, even though portions of the text of the +# Macro appear in them. The GNU General Public License (GPL) does govern +# all other use of the material that constitutes the Autoconf Macro. +# +# This special exception to the GPL applies to versions of the Autoconf +# Macro released by the Autoconf Macro Archive. When you make and +# distribute a modified version of the Autoconf Macro, you may extend this +# special exception to the GPL to apply to your modified version as well. + +AC_DEFUN([AX_CHECK_COMPILER_FLAGS], +[AC_PREREQ(2.59) dnl for _AC_LANG_PREFIX +AC_MSG_CHECKING([whether _AC_LANG compiler accepts $1]) +dnl Some hackery here since AC_CACHE_VAL can't handle a non-literal varname: +AS_LITERAL_IF([$1], + [AC_CACHE_VAL(AS_TR_SH(ax_cv_[]_AC_LANG_ABBREV[]_flags_$1), [ + ax_save_FLAGS=$[]_AC_LANG_PREFIX[]FLAGS + _AC_LANG_PREFIX[]FLAGS="$1" + AC_COMPILE_IFELSE([AC_LANG_PROGRAM()], + AS_TR_SH(ax_cv_[]_AC_LANG_ABBREV[]_flags_$1)=yes, + AS_TR_SH(ax_cv_[]_AC_LANG_ABBREV[]_flags_$1)=no) + _AC_LANG_PREFIX[]FLAGS=$ax_save_FLAGS])], + [ax_save_FLAGS=$[]_AC_LANG_PREFIX[]FLAGS + _AC_LANG_PREFIX[]FLAGS="$1" + AC_COMPILE_IFELSE([AC_LANG_PROGRAM()], + eval AS_TR_SH(ax_cv_[]_AC_LANG_ABBREV[]_flags_$1)=yes, + eval AS_TR_SH(ax_cv_[]_AC_LANG_ABBREV[]_flags_$1)=no) + _AC_LANG_PREFIX[]FLAGS=$ax_save_FLAGS]) +eval ax_check_compiler_flags=$AS_TR_SH(ax_cv_[]_AC_LANG_ABBREV[]_flags_$1) +AC_MSG_RESULT($ax_check_compiler_flags) +if test "x$ax_check_compiler_flags" = xyes; then + m4_default([$2], :) +else + m4_default([$3], :) +fi +])dnl AX_CHECK_COMPILER_FLAGS Index: src/Makefile ================================================================== --- src/Makefile +++ src/Makefile @@ -4,10 +4,11 @@ LIB_MAJOR = 1 LIB_MINOR = 0 SRCS = OFArray.m \ OFAutoreleasePool.m \ + OFConstString.m \ OFDictionary.m \ OFExceptions.m \ OFHashes.m \ OFFile.m \ OFList.m \ ADDED src/OFConstString.h Index: src/OFConstString.h ================================================================== --- src/OFConstString.h +++ src/OFConstString.h @@ -0,0 +1,49 @@ +/* + * Copyright (c) 2008 - 2009 + * Jonathan Schleifer + * + * All rights reserved. + * + * This file is part of libobjfw. It may be distributed under the terms of the + * Q Public License 1.0, which can be found in the file LICENSE included in + * the packaging of this file. + */ + +#import "OFObject.h" + +#if !defined(__objc_INCLUDE_GNU) && !defined(OFCONSTSTRING_M) +/* + * This way, projects using libobjfw don't need -Wno-deprecated-declarations on + * OS X 10.5. + */ +extern void _OFConstStringClassReference; +#endif + +/** + * A class for storing static strings using the @"" literal. + */ +@interface OFConstString: Object +{ + char *string; + size_t length; +} + +/** + * \return The OFString as a C string + */ +- (const char*)cString; + +/** + * \return The length of the OFString + */ +- (size_t)length; + +/** + * Compares the OFString to another object. + * + * \param obj An object to compare with + * \return An integer which is the result of the comparison, see for example + * strcmp + */ +- (int)compare: (id)obj; +@end ADDED src/OFConstString.m Index: src/OFConstString.m ================================================================== --- src/OFConstString.m +++ src/OFConstString.m @@ -0,0 +1,107 @@ +/* + * Copyright (c) 2008 - 2009 + * Jonathan Schleifer + * + * All rights reserved. + * + * This file is part of libobjfw. It may be distributed under the terms of the + * Q Public License 1.0, which can be found in the file LICENSE included in + * the packaging of this file. + */ + +#import "config.h" + +#include +#include +#include + +#define OFCONSTSTRING_M +#import "OFConstString.h" +#import "OFString.h" +#import "OFExceptions.h" +#import "OFMacros.h" + +#ifndef __objc_INCLUDE_GNU +struct objc_class _OFConstStringClassReference; +#endif + +@implementation OFConstString +#ifndef __objc_INCLUDE_GNU ++ (void)load +{ + Class cls = objc_getClass("OFConstString"); + memcpy(&_OFConstStringClassReference, cls, + sizeof(_OFConstStringClassReference)); + objc_addClass(&_OFConstStringClassReference); +} +#endif + +- (BOOL)isKindOf: (Class)c +{ + if (c == [OFConstString class]) + return YES; + return NO; +} + +- (const char*)cString +{ + return string; +} + +- (size_t)length +{ + return length; +} + +- (BOOL)isEqual: (id)obj +{ + if (![obj isKindOf: [OFString class]] && + ![obj isKindOf: [OFConstString class]]) + return NO; + if (strcmp(string, [obj cString])) + return NO; + + return YES; +} + +- (int)compare: (id)obj +{ + if (![obj isKindOf: [OFString class]] && + ![obj isKindOf: [OFConstString class]]) + @throw [OFInvalidArgumentException newWithClass: [self class]]; + + return strcmp(string, [obj cString]); +} + +- (uint32_t)hash +{ + uint32_t hash; + size_t i; + + OF_HASH_INIT(hash); + for (i = 0; i < length; i++) + OF_HASH_ADD(hash, string[i]); + OF_HASH_FINALIZE(hash); + + return hash; +} + +- retain +{ + return self; +} + +- (void)release +{ +} + +- (size_t)retainCount +{ + return 1; +} + +- autorelease +{ + return self; +} +@end Index: src/OFDictionary.h ================================================================== --- src/OFDictionary.h +++ src/OFDictionary.h @@ -55,21 +55,21 @@ * Sets a key to an object. A key can be any object. * * \param key The key to set * \param obj The object to set the key to */ -- set: (OFObject*)key - to: (OFObject*)obj; +- set: (id )key + to: (id )obj; /* * \param key The key whose object should be returned * \return The object for the given key */ -- get: (OFObject*)key; +- get: (id )key; /* * Remove the object with the given key from the dictionary. * * \param key The key whose object should be removed */ -- remove: (OFObject*)key; +- remove: (id )key; @end Index: src/OFDictionary.m ================================================================== --- src/OFDictionary.m +++ src/OFDictionary.m @@ -78,12 +78,12 @@ [data[i] release]; return [super free]; } -- set: (OFObject*)key - to: (OFObject*)obj +- set: (id )key + to: (id )obj { uint32_t hash = [key hash] & (size - 1); of_list_object_t *iter; if (data[hash] == nil) @@ -107,11 +107,11 @@ [data[hash] append: obj]; return self; } -- get: (OFObject*)key +- get: (id )key { uint32_t hash = [key hash] & (size - 1); of_list_object_t *iter; if (data[hash] == nil) @@ -122,11 +122,11 @@ return iter->next->object; return nil; } -- remove: (OFObject*)key +- remove: (id )key { uint32_t hash = [key hash] & (size - 1); of_list_object_t *iter; if (data[hash] == nil) Index: src/OFObject.h ================================================================== --- src/OFObject.h +++ src/OFObject.h @@ -11,28 +11,11 @@ #import #include -/** - * The OFObject class is the base class for all other classes inside ObjFW. - */ -@interface OFObject: Object -{ - void **__memchunks; - size_t __memchunks_size; - size_t __retain_count; -} - -/** - * Initialize the already allocated object. - * Also sets up the memory pool for the object. - * - * \return An initialized object - */ -- init; - +@protocol OFRetainRelease /** * Increases the retain count. */ - retain; @@ -48,16 +31,13 @@ /** * \return The retain count */ - (size_t)retainCount; +@end -/** - * Frees the object and also frees all memory allocated via its memory pool. - */ -- free; - +@protocol OFHashable /** * Compare two objects. * Classes containing data (like strings, arrays, lists etc.) should reimplement * this! * @@ -72,10 +52,34 @@ * this! * * \return A 24 bit hash for the object */ - (uint32_t)hash; +@end + +/** + * The OFObject class is the base class for all other classes inside ObjFW. + */ +@interface OFObject: Object +{ + void **__memchunks; + size_t __memchunks_size; + size_t __retain_count; +} + +/** + * Initialize the already allocated object. + * Also sets up the memory pool for the object. + * + * \return An initialized object + */ +- init; + +/** + * Frees the object and also frees all memory allocated via its memory pool. + */ +- free; /** * Adds a pointer to the memory pool. * This is useful to add memory allocated by functions such as asprintf to the * pool so it gets freed automatically when the object is freed. Index: src/OFString.h ================================================================== --- src/OFString.h +++ src/OFString.h @@ -91,11 +91,11 @@ */ - initWithFormat: (const char*)fmt andArguments: (va_list)args; /** - * \return The OFString as a wide C string + * \return The OFString as a C string */ - (const char*)cString; /** * \return The length of the OFString Index: src/OFString.m ================================================================== --- src/OFString.m +++ src/OFString.m @@ -23,10 +23,11 @@ #else #define madvise(addr, len, advise) #endif #import "OFString.h" +#import "OFConstString.h" #import "OFExceptions.h" #import "OFMacros.h" #ifndef HAVE_ASPRINTF #import "asprintf.h" @@ -275,21 +276,23 @@ return self; } - (BOOL)isEqual: (id)obj { - if (![obj isKindOf: [OFString class]]) + if (![obj isKindOf: [OFString class]] && + ![obj isKindOf: [OFConstString class]]) return NO; if (strcmp(string, [obj cString])) return NO; return YES; } - (int)compare: (id)obj { - if (![obj isKindOf: [OFString class]]) + if (![obj isKindOf: [OFString class]] && + ![obj isKindOf: [OFConstString class]]) @throw [OFInvalidArgumentException newWithClass: [self class]]; return strcmp(string, [obj cString]); } Index: tests/OFDictionary/OFDictionary.m ================================================================== --- tests/OFDictionary/OFDictionary.m +++ tests/OFDictionary/OFDictionary.m @@ -13,10 +13,11 @@ #import #import "OFAutoreleasePool.h" #import "OFDictionary.h" +#import "OFConstString.h" #import "OFString.h" int main() { @@ -32,10 +33,10 @@ to: value1]; [dict set: key2 to: value2]; [pool release]; - puts([[dict get: key1] cString]); + puts([[dict get: @"key1"] cString]); puts([[dict get: key2] cString]); return 0; }