ObjFW  Check-in [2ff44fe8d7]

Overview
Comment:Preliminary OFConstString implementation and support for @"" literals.
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA3-256: 2ff44fe8d72e56759a28918329f78840a166b2f6a54078125f3dba7c705cb3d5
User & Date: js on 2009-03-15 13:46:24
Other Links: manifest | tags
Context
2009-03-15
16:14
$target -> $host check-in: b58e44112a user: js tags: trunk
13:46
Preliminary OFConstString implementation and support for @"" literals. check-in: 2ff44fe8d7 user: js tags: trunk
2009-03-14
17:17
Preliminary OFPlugin implementation.
Win32 isn't supported yet due to the problems libobjc + DLLs.
check-in: 2e13035431 user: js tags: trunk
Changes

Modified configure.ac from [6672b28534] to [705da61df5].

1
2
3
4
5
6
7
8
9
10
11
12
13
14

15
16






17
18
19
20
21
22
23
1
2
3
4

5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29




-









+


+
+
+
+
+
+







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])

if test x"$PLUGIN_SUFFIX" != "x"; then
	AC_SUBST(OFPLUGIN_M, "OFPlugin.m")
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
135
136
137
138
139
140
141



142
143
144
145
146
147
148







-
-
-







		ac_cv_have_ipv6="no")])
AC_MSG_RESULT($ac_cv_have_ipv6)
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)

			if test x"$WINE" != "x"; then
				AC_SUBST(TESTS, "tests")

Added m4/ax_check_compiler_flags.m4 version [eb1353b82e].















































































1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
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 <stevenj@alum.mit.edu>
#   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 <http://www.gnu.org/licenses/>.
#
#   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

Modified src/Makefile from [325a4e921c] to [549491be05].

1
2
3
4
5
6
7
8

9
10
11
12
13
14
15
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16








+







include ../extra.mk

LIB = ${LIB_PREFIX}objfw${LIB_SUFFIX}
LIB_MAJOR = 1
LIB_MINOR = 0

SRCS = OFArray.m		\
       OFAutoreleasePool.m	\
       OFConstString.m		\
       OFDictionary.m		\
       OFExceptions.m		\
       OFHashes.m		\
       OFFile.m			\
       OFList.m			\
       OFNumber.m		\
       OFObject.m		\

Added src/OFConstString.h version [e717b6350a].


















































1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
/*
 * Copyright (c) 2008 - 2009
 *   Jonathan Schleifer <js@webkeks.org>
 *
 * 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 <OFHashable, OFRetainRelease>
{
	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 version [ebbddd5fa7].












































































































1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
/*
 * Copyright (c) 2008 - 2009
 *   Jonathan Schleifer <js@webkeks.org>
 *
 * 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 <stdio.h>
#include <stdlib.h>
#include <string.h>

#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

Modified src/OFDictionary.h from [0e40b77f27] to [6fa1c50c8b].

53
54
55
56
57
58
59
60
61


62
63
64
65
66
67

68
69
70
71
72
73
74

75
53
54
55
56
57
58
59


60
61
62
63
64
65
66

67
68
69
70
71
72
73

74
75







-
-
+
+





-
+






-
+


/*
 * 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 <OFHashable, OFRetainRelease>)key
   to: (id <OFRetainRelease>)obj;

/*
 * \param key The key whose object should be returned
 * \return The object for the given key
 */
- get: (OFObject*)key;
- get: (id <OFHashable>)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 <OFHashable, OFRetainRelease>)key;
@end

Modified src/OFDictionary.m from [fa7f05506c] to [e494105a2e].

76
77
78
79
80
81
82
83
84


85
86
87
88
89
90
91
76
77
78
79
80
81
82


83
84
85
86
87
88
89
90
91







-
-
+
+







	for (i = 0; i < size; i++)
		if (data[i] != nil)
			[data[i] release];

	return [super free];
}

- set: (OFObject*)key
   to: (OFObject*)obj
- set: (id <OFHashable, OFRetainRelease>)key
   to: (id <OFRetainRelease>)obj
{
	uint32_t hash = [key hash] & (size - 1);
	of_list_object_t *iter;

	if (data[hash] == nil)
		data[hash] = [OFList new];

105
106
107
108
109
110
111
112

113
114
115
116
117
118
119
120
121
122
123
124
125
126
127

128
129
130
131
132
133
134
105
106
107
108
109
110
111

112
113
114
115
116
117
118
119
120
121
122
123
124
125
126

127
128
129
130
131
132
133
134







-
+














-
+








	[data[hash] append: key];
	[data[hash] append: obj];

	return self;
}

- get: (OFObject*)key
- get: (id <OFHashable>)key
{
	uint32_t hash = [key hash] & (size - 1);
	of_list_object_t *iter;

	if (data[hash] == nil)
		return nil;

	for (iter = [data[hash] first]; iter != NULL; iter = iter->next->next)
		if ([iter->object isEqual: key])
			return iter->next->object;

	return nil;
}

- remove: (OFObject*)key
- remove: (id <OFHashable, OFRetainRelease>)key
{
	uint32_t hash = [key hash] & (size - 1);
	of_list_object_t *iter;

	if (data[hash] == nil)
		return self; // FIXME: Throw exception?

Modified src/OFObject.h from [a404ee9968] to [1af8420b56].

9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25

26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53

54
55
56
57
58

59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
























77
78
79
80
81
82
83
9
10
11
12
13
14
15










16








17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35

36




37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87







-
-
-
-
-
-
-
-
-
-
+
-
-
-
-
-
-
-
-



















-
+
-
-
-
-

+


















+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+







 * the packaging of this file.
 */

#import <objc/Object.h>

#include <stdint.h>

/**
 * 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;
}

@protocol OFRetainRelease
/**
 * Initialize the already allocated object.
 * Also sets up the memory pool for the object.
 *
 * \return An initialized object
 */
- init;

/**
 * Increases the retain count.
 */
- retain;

/**
 * Decreases the retain cound and frees the object if it reaches 0.
 */
- (void)release;

/**
 * Adds the object to the autorelease pool that is on top of the thread's stack.
 */
- autorelease;

/**
 * \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!
 *
 * \param obj The object which is tested for equality
 * \return A boolean whether the object is equal to the other object
 */
- (BOOL)isEqual: (id)obj;

/**
 * Calculate a hash for the object.
 * Classes containing data (like strings, arrays, lists etc.) should reimplement
 * 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 <OFRetainRelease, OFHashable>
{
	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.
 *
 * \param ptr A pointer to add to the memory pool

Modified src/OFString.h from [6da443a86b] to [2275e1b033].

89
90
91
92
93
94
95
96

97
98
99
100
101
102
103
89
90
91
92
93
94
95

96
97
98
99
100
101
102
103







-
+







 * \param args The arguments used in the format string
 * \return An initialized OFString
 */
- 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
 */
- (size_t)length;

Modified src/OFString.m from [365ef7f711] to [0784bdbb56].

21
22
23
24
25
26
27

28
29
30
31
32
33
34
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35







+







#ifdef HAVE_SYS_MMAN_H
#include <sys/mman.h>
#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"
#endif

273
274
275
276
277
278
279
280


281
282
283
284
285
286
287
288
289
290


291
292
293
294
295
296
297
274
275
276
277
278
279
280

281
282
283
284
285
286
287
288
289
290
291

292
293
294
295
296
297
298
299
300







-
+
+









-
+
+







	memcpy(string, str, length + 1);

	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]);
}

- (uint32_t)hash
{

Modified tests/OFDictionary/OFDictionary.m from [d476405c0d] to [18eeb7ebbc].

11
12
13
14
15
16
17

18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37

38
39
40
41
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37

38
39
40
41
42







+



















-
+





#import "config.h"

#import <stdio.h>

#import "OFAutoreleasePool.h"
#import "OFDictionary.h"
#import "OFConstString.h"
#import "OFString.h"

int
main()
{
	OFDictionary *dict = [OFDictionary dictionaryWithHashSize: 16];

	OFAutoreleasePool *pool = [OFAutoreleasePool new];
	OFString *key1 = [OFString stringWithCString: "key1"];
	OFString *key2 = [OFString stringWithCString: "key2"];
	OFString *value1 = [OFString stringWithCString: "value1"];
	OFString *value2 = [OFString stringWithCString: "value2"];

	[dict set: key1
	       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;
}