-
Notifications
You must be signed in to change notification settings - Fork 4
/
Copy path_MiscMergeProcedureCommand.m
executable file
·186 lines (155 loc) · 5.83 KB
/
_MiscMergeProcedureCommand.m
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
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
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
//
// _MiscMergeProcedureCommand.m
//
// Written by Don Yacktman and Carl Lindberg
//
// Copyright 2001-2004 by Don Yacktman and Carl Lindberg.
// All rights reserved.
//
// This notice may not be removed from this source code.
//
// This header is included in the MiscKit by permission from the author
// and its use is governed by the MiscKit license, found in the file
// "License.rtf" in the MiscKit distribution. Please refer to that file
// for a list of all applicable permissions and restrictions.
//
#import "_MiscMergeProcedureCommand.h"
#import <Foundation/Foundation.h>
#import "MiscMergeEngine.h"
#import "MiscMergeTemplate.h"
#import "MiscMergeCommandBlock.h"
#import "NSNull.h"
#import "NSScanner+MiscMerge.h"
typedef enum _ArgTypes {
RequiredArg = 1,
OptionalArg = 2,
ArrayArg = 3
} ArgTypes;
@implementation _MiscMergeProcedureCommand
- init
{
[super init];
commandBlock = [[MiscMergeCommandBlock alloc] initWithOwner:self];
argumentArray = [[NSMutableArray alloc] init];
argumentTypes = [[NSMutableArray alloc] init];
return self;
}
- (void)dealloc
{
[commandBlock release];
[procedureName release];
[argumentArray release];
[argumentTypes release];
[super dealloc];
}
- (NSString *)procedureName
{
return procedureName;
}
- (BOOL)parseFromScanner:(NSScanner *)aScanner template:(MiscMergeTemplate *)template
{
NSString *argName;
BOOL optArgProcessing = NO;
[self eatKeyWord:@"procedure" fromScanner:aScanner isOptional:NO];
procedureName = [[self getArgumentStringFromScanner:aScanner toEnd:NO] retain];
while ((argName = [self getArgumentStringFromScanner:aScanner toEnd:NO])) {
if ( [argName hasSuffix:@"?"] ) {
optArgProcessing = YES;
argName = [argName substringToIndex:([argName length] - 1)];
[argumentTypes addObject:[NSNumber numberWithInt:OptionalArg]];
}
else if ( [argName hasSuffix:@"..."] ) {
argName = [argName substringToIndex:([argName length] - 3)];
[aScanner remainingString];
[argumentTypes addObject:[NSNumber numberWithInt:ArrayArg]];
}
else if ( optArgProcessing ) {
[template reportParseError:@"%@: Can only specify optional arguments after an initial optional argument: \"%@\".", procedureName, argName];
return NO;
}
else {
[argumentTypes addObject:[NSNumber numberWithInt:RequiredArg]];
}
[argumentArray addObject:argName];
}
[template pushCommandBlock:commandBlock];
return YES;
}
- (void)handleEndProcedureInTemplate:(MiscMergeTemplate *)template
{
[template popCommandBlock:commandBlock];
}
- (MiscMergeCommandExitType)executeForMerge:(MiscMergeEngine *)aMerger
{
/* Just want to register ourselves to the engine */
NSString *symbolName = [NSString stringWithFormat:@"_MiscMergeProcedure%@", procedureName];
[[aMerger userInfo] setObject:self forKey:symbolName];
return MiscMergeCommandExitNormal;
}
/* The *real* execute; messaged from the call command */
- (MiscMergeCommandExitType)executeForMerge:(MiscMergeEngine *)aMerger arguments:(NSArray *)passedArgArray
{
NSInteger argumentIndex = 0, argumentCount = [argumentArray count];
NSInteger passedIndex = 0, passedCount = [passedArgArray count];
NSInteger addToArgIndex = 0;
NSMutableDictionary *procedureContext = [NSMutableDictionary dictionary];
for ( ; passedIndex < passedCount; passedIndex++ ) {
NSString *argName;
int argType;
id argValue = [passedArgArray objectAtIndex:passedIndex];
if ( argumentIndex >= argumentCount ) {
NSLog(@"%@: More arguments than declared.", procedureName);
break;
}
argName = [argumentArray objectAtIndex:argumentIndex];
argType = [[argumentTypes objectAtIndex:argumentIndex] intValue];
switch ( argType ) {
case RequiredArg:
case OptionalArg:
if ( argValue == [NSNull null] )
argValue = @"";
[procedureContext setObject:argValue forKey:argName];
argumentIndex++;
break;
case ArrayArg:
{
NSMutableArray *array = [procedureContext objectForKey:argName];
if ( array == nil ) {
array = [NSMutableArray array];
[procedureContext setObject:array forKey:argName];
}
addToArgIndex = 1;
[array addObject:argValue];
}
break;
}
}
argumentIndex += addToArgIndex;
/* Insure any optional parameters get set to "" and log any required parameters there were not
gotten in the call. */
if ( argumentIndex < argumentCount ) {
NSMutableString *string = [NSMutableString string];
for ( ; argumentIndex < argumentCount; argumentIndex++ ) {
NSString *argName = [argumentArray objectAtIndex:argumentIndex];
int argType = [[argumentTypes objectAtIndex:argumentIndex] intValue];
if ( argType == OptionalArg ) {
[procedureContext setObject:@"" forKey:argName];
}
else if ( argType == ArrayArg ) {
[procedureContext setObject:[NSArray array] forKey:argName];
}
else {
if ( [string length] > 0 )
[string appendString:@", "];
[string appendString:argName];
}
}
if ( [string length] > 0 )
NSLog(@"%@: Missing arguments for: %@", procedureName, string);
}
[aMerger addContextObject:procedureContext andSetLocalSymbols:YES];
[aMerger executeCommandBlock:commandBlock];
[aMerger removeContextObject:procedureContext];
return MiscMergeCommandExitNormal;
}
@end