ObjFW  Check-in [759d73547f]

Overview
Comment:objfw-new: Add initial support for properties
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA3-256: 759d73547f94c7ea421161ee621d896570fc06ddf57bf13ea5ca69cc008af663
User & Date: js on 2022-08-07 23:49:03
Other Links: manifest | tags
Context
2022-08-08
18:53
objfw-new: Add support for property attributes check-in: 41bf4fe57b user: js tags: trunk
2022-08-07
23:49
objfw-new: Add initial support for properties check-in: 759d73547f user: js tags: trunk
21:26
Make GCC happy again check-in: d54804e886 user: js tags: trunk
Changes

Modified utils/objfw-new/Makefile from [c4471397ec] to [fe068759c6].

1
2
3
4
5
6

7
8
9
10
11
12
13
include ../../extra.mk

PROG = objfw-new${PROG_SUFFIX}
SRCS = NewApp.m		\
       NewClass.m	\
       ObjFWNew.m


include ../../buildsys.mk

${PROG}: ${LIBOBJFW_DEP_LVL2} ${LIBOBJFWRT_DEP_LVL2}

CPPFLAGS += -I../../src					\
	    -I../../src/runtime				\





|
>







1
2
3
4
5
6
7
8
9
10
11
12
13
14
include ../../extra.mk

PROG = objfw-new${PROG_SUFFIX}
SRCS = NewApp.m		\
       NewClass.m	\
       ObjFWNew.m	\
       Property.m

include ../../buildsys.mk

${PROG}: ${LIBOBJFW_DEP_LVL2} ${LIBOBJFWRT_DEP_LVL2}

CPPFLAGS += -I../../src					\
	    -I../../src/runtime				\

Modified utils/objfw-new/NewClass.m from [eadf67910a] to [7272551759].

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
 * LICENSE.GPLv2 or LICENSE.GPLv3 respectively included in the packaging of this
 * file.
 */

#include "config.h"

#include <errno.h>



#import "OFApplication.h"

#import "OFFile.h"
#import "OFStdIOStream.h"
#import "OFString.h"

#import "OFOpenItemFailedException.h"

void
newClass(OFString *name, OFString *superclass)
{
	OFString *headerPath = [name stringByAppendingPathExtension: @"h"];
	OFString *implPath = [name stringByAppendingPathExtension: @"m"];
	OFFile *headerFile = nil, *implFile = nil;
	@try {
		headerFile = [OFFile fileWithPath: headerPath mode: @"wx"];
		implFile = [OFFile fileWithPath: implPath mode: @"wx"];
	} @catch (OFOpenItemFailedException *e) {
		if (e.errNo != EEXIST)
			@throw e;

		[OFStdErr writeFormat: @"File %@ already exists! Aborting...\n",
				       e.path];
		[OFApplication terminateWithStatus: 1];
	}

	if (superclass == nil)
		superclass = @"OFObject";








	[headerFile writeFormat: @"#import <ObjFW/ObjFW.h>\n"
				 @"\n"


				 @"@interface %@: %@\n"
				 @"@end\n",
				 name, superclass];



















	[implFile writeFormat: @"#import \"%@\"\n"
			       @"\n"
			       @"@implementation %@\n"
			       @"@end\n",
			       headerPath, name];







	[headerFile close];
	[implFile close];
}








>
>

>







|


















>
>
>
>
>
>
>



>
>
|
<


>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>


|
<

>
>
>
>
>
>




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
 * LICENSE.GPLv2 or LICENSE.GPLv3 respectively included in the packaging of this
 * file.
 */

#include "config.h"

#include <errno.h>

#import "Property.h"

#import "OFApplication.h"
#import "OFArray.h"
#import "OFFile.h"
#import "OFStdIOStream.h"
#import "OFString.h"

#import "OFOpenItemFailedException.h"

void
newClass(OFString *name, OFString *superclass, OFMutableArray *properties)
{
	OFString *headerPath = [name stringByAppendingPathExtension: @"h"];
	OFString *implPath = [name stringByAppendingPathExtension: @"m"];
	OFFile *headerFile = nil, *implFile = nil;
	@try {
		headerFile = [OFFile fileWithPath: headerPath mode: @"wx"];
		implFile = [OFFile fileWithPath: implPath mode: @"wx"];
	} @catch (OFOpenItemFailedException *e) {
		if (e.errNo != EEXIST)
			@throw e;

		[OFStdErr writeFormat: @"File %@ already exists! Aborting...\n",
				       e.path];
		[OFApplication terminateWithStatus: 1];
	}

	if (superclass == nil)
		superclass = @"OFObject";

	for (size_t i = 0; i < properties.count; i++) {
		Property *property = [Property propertyWithString:
		    [properties objectAtIndex: i]];
		[properties replaceObjectAtIndex: i
				      withObject: property];
	}

	[headerFile writeFormat: @"#import <ObjFW/ObjFW.h>\n"
				 @"\n"
				 @"OF_ASSUME_NONNULL_BEGIN\n"
				 @"\n"
				 @"@interface %@: %@\n",

				 name, superclass];

	if (properties.count > 0)
		[headerFile writeString: @"{\n"];

	for (Property *property in properties)
		[headerFile writeFormat: @"\t%@_%@;\n",
					 property.type, property.name];

	if (properties.count > 0)
		[headerFile writeString: @"}\n\n"];

	for (Property *property in properties)
		[headerFile writeFormat: @"@property %@%@;\n",
					 property.type, property.name];

	[headerFile writeString: @"@end\n"
				 @"\n"
				 @"OF_ASSUME_NONNULL_END\n"];

	[implFile writeFormat: @"#import \"%@\"\n"
			       @"\n"
			       @"@implementation %@\n",

			       headerPath, name];

	for (Property *property in properties)
		[implFile writeFormat: @"@synthesize %@ = _%@;\n",
				       property.name, property.name];

	[implFile writeString: @"@end\n"];

	[headerFile close];
	[implFile close];
}

Modified utils/objfw-new/ObjFWNew.m from [28e90aedf9] to [620606a28a].

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
#import "OFStdIOStream.h"
#import "OFString.h"

@interface ObjFWNew: OFObject <OFApplicationDelegate>
@end

extern void newApp(OFString *);
extern void newClass(OFString *, OFString *);

OF_APPLICATION_DELEGATE(ObjFWNew)

static void
showUsage(void)
{
	[OFStdErr writeFormat: @"Usage: %@ --app|--class name\n",
			       [OFApplication programName]];

	[OFApplication terminateWithStatus: 1];
}

@implementation ObjFWNew
- (void)applicationDidFinishLaunching
{
	bool app, class;
	OFString *superclass = nil;

	const OFOptionsParserOption options[] = {
		{ '\0', @"app", 0, &app, NULL },
		{ '\0', @"class", 0, &class, NULL },
		{ '\0', @"superclass", 1, NULL, &superclass },

		{ '\0', nil, 0, NULL, NULL }
	};
	OFOptionsParser *optionsParser;
	OFUnichar option;

	optionsParser = [OFOptionsParser parserWithOptions: options];
	while ((option = [optionsParser nextOption]) != '\0')






		if (option == '?' || option == ':' || option == '=')






			showUsage();




	if ((app ^ class) != 1 || optionsParser.remainingArguments.count != 1)
		showUsage();

	if (superclass && !class)
		showUsage();

	if (app)
		newApp(optionsParser.remainingArguments.firstObject);
	else if (class)
		newClass(optionsParser.remainingArguments.firstObject,
		    superclass);
	else
		showUsage();

	[OFApplication terminate];
}
@end







|

















>




>






|
>
>
>
>
>
>
|
>
>
>
>
>
>

>
>
>




|






|






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
#import "OFStdIOStream.h"
#import "OFString.h"

@interface ObjFWNew: OFObject <OFApplicationDelegate>
@end

extern void newApp(OFString *);
extern void newClass(OFString *, OFString *, OFMutableArray *);

OF_APPLICATION_DELEGATE(ObjFWNew)

static void
showUsage(void)
{
	[OFStdErr writeFormat: @"Usage: %@ --app|--class name\n",
			       [OFApplication programName]];

	[OFApplication terminateWithStatus: 1];
}

@implementation ObjFWNew
- (void)applicationDidFinishLaunching
{
	bool app, class;
	OFString *superclass = nil;
	OFMutableArray OF_GENERIC(OFString *) *properties = nil;
	const OFOptionsParserOption options[] = {
		{ '\0', @"app", 0, &app, NULL },
		{ '\0', @"class", 0, &class, NULL },
		{ '\0', @"superclass", 1, NULL, &superclass },
		{ '\0', @"property", 1, NULL, NULL },
		{ '\0', nil, 0, NULL, NULL }
	};
	OFOptionsParser *optionsParser;
	OFUnichar option;

	optionsParser = [OFOptionsParser parserWithOptions: options];
	while ((option = [optionsParser nextOption]) != '\0') {
		switch (option) {
		case '-':;
			if ([optionsParser.lastLongOption
			    isEqual: @"property"]) {
				if (properties == nil)
					properties = [OFMutableArray array];

				[properties addObject: optionsParser.argument];
			}
			break;
		case '?':
		case ':':
		case '=':
			showUsage();
			break;
		}
	}

	if ((app ^ class) != 1 || optionsParser.remainingArguments.count != 1)
		showUsage();

	if ((superclass && !class)  || (properties != nil && !class))
		showUsage();

	if (app)
		newApp(optionsParser.remainingArguments.firstObject);
	else if (class)
		newClass(optionsParser.remainingArguments.firstObject,
		    superclass, properties);
	else
		showUsage();

	[OFApplication terminate];
}
@end

Added utils/objfw-new/Property.h version [e95ce45cc0].



































































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
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
/*
 * Copyright (c) 2008-2022 Jonathan Schleifer <js@nil.im>
 *
 * All rights reserved.
 *
 * This file is part of ObjFW. It may be distributed under the terms of the
 * Q Public License 1.0, which can be found in the file LICENSE.QPL included in
 * the packaging of this file.
 *
 * Alternatively, it may be distributed under the terms of the GNU General
 * Public License, either version 2 or 3, which can be found in the file
 * LICENSE.GPLv2 or LICENSE.GPLv3 respectively included in the packaging of this
 * file.
 */

#import "OFObject.h"
#import "OFString.h"

OF_ASSUME_NONNULL_BEGIN

@interface Property: OFObject
{
	OFString *_name, *_type;
}

+ (instancetype)propertyWithString: (OFString *)string;
- (instancetype)initWithString: (OFString *)string;

@property (readonly, nonatomic) OFString *name;
@property (readonly, nonatomic) OFString *type;
@end

OF_ASSUME_NONNULL_END

Added utils/objfw-new/Property.m version [25213351ae].

































































































































































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
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
/*
 * Copyright (c) 2008-2022 Jonathan Schleifer <js@nil.im>
 *
 * All rights reserved.
 *
 * This file is part of ObjFW. It may be distributed under the terms of the
 * Q Public License 1.0, which can be found in the file LICENSE.QPL included in
 * the packaging of this file.
 *
 * Alternatively, it may be distributed under the terms of the GNU General
 * Public License, either version 2 or 3, which can be found in the file
 * LICENSE.GPLv2 or LICENSE.GPLv3 respectively included in the packaging of this
 * file.
 */

#include "config.h"

#import "Property.h"

#import "OFInvalidArgumentException.h"
#import "OFOutOfRangeException.h"

@interface Property ()
- (void)parseString: (OFString *)string;
@end

@implementation Property
@synthesize name = _name, type = _type;

+ (instancetype)propertyWithString: (OFString *)string
{
	return [[[self alloc] initWithString: string] autorelease];
}

- (instancetype)initWithString: (OFString *)string
{
	self = [super init];

	@try {
		[self parseString: string];
	} @catch (id e) {
		[self release];
		@throw e;
	}

	return self;
}

- (void)parseString: (OFString *)string
{
	const char *UTF8String = string.UTF8String;
	size_t length = string.UTF8StringLength, nameIdx = -1;

	if (length > SSIZE_MAX)
		@throw [OFOutOfRangeException exception];

	for (ssize_t i = (ssize_t)length - 1; i > 0; i--) {
		if (UTF8String[i] == '*' || UTF8String[i] == ' ' ||
		    UTF8String[i] == '\t') {
			nameIdx = i + 1;
			break;
		}
	}

	if (nameIdx < 0)
		@throw [OFInvalidArgumentException exception];

	_name = [[OFString alloc] initWithUTF8String: UTF8String + nameIdx];
	_type = [[OFString alloc] initWithUTF8String: UTF8String
					      length: (size_t)nameIdx];
}

- (void)dealloc
{
	[_name release];
	[_type release];

	[super dealloc];
}
@end