Oolite 1.91.0.7604-240417-a536cbe
Loading...
Searching...
No Matches
OOConvertSystemDescriptions.m
Go to the documentation of this file.
1/*
2
3OOConvertSystemDescriptions.m
4Oolite
5
6
7Copyright (C) 2008 Jens Ayton
8
9Permission is hereby granted, free of charge, to any person obtaining a copy
10of this software and associated documentation files (the "Software"), to deal
11in the Software without restriction, including without limitation the rights
12to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
13copies of the Software, and to permit persons to whom the Software is
14furnished to do so, subject to the following conditions:
15
16The above copyright notice and this permission notice shall be included in all
17copies or substantial portions of the Software.
18
19THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
20IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
21FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
22AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
23LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
24OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
25SOFTWARE.
26
27*/
28
29#import "Universe.h"
30
31
32#if OO_LOCALIZATION_TOOLS
33
37#import "ResourceManager.h"
38
39static NSMutableDictionary *InitKeyToIndexDict(NSDictionary *dict, NSMutableSet **outUsedIndices);
40static NSString *IndexToKey(NSUInteger index, NSDictionary *indicesToKeys, BOOL useFallback);
41static NSArray *ConvertIndicesToKeys(NSArray *entry, NSDictionary *indicesToKeys);
42static NSNumber *KeyToIndex(NSString *key, NSMutableDictionary *ioKeysToIndices, NSMutableSet *ioUsedIndicies, NSUInteger *ioSlotCache);
43static NSArray *ConvertKeysToIndices(NSArray *entry, NSMutableDictionary *ioKeysToIndices, NSMutableSet *ioUsedIndicies, NSUInteger *ioSlotCache);
44static NSUInteger HighestIndex(NSMutableDictionary *sparseArray); // Actually returns highest index + 1, which is fine.
45
46
48{
49 NSDictionary *sysDescDict = nil;
50 NSArray *sysDescArray = nil;
51 NSDictionary *keyMap = nil;
52 NSData *data = nil;
53 NSString *error = nil;
54
55 sysDescDict = [ResourceManager dictionaryFromFilesNamed:@"sysdesc.plist"
56 inFolder:@"Config"
57 andMerge:NO];
58 if (sysDescDict == nil)
59 {
60 OOLog(@"sysdesc.compile.failed.fileNotFound", @"%@", @"Could not load a dictionary from sysdesc.plist, ignoring --compile-sysdesc option.");
61 return;
62 }
63
64 keyMap = [ResourceManager dictionaryFromFilesNamed:@"sysdesc_key_table.plist"
65 inFolder:@"Config"
66 andMerge:NO];
67 // keyMap is optional, so no nil check
68
69 sysDescArray = OOConvertSystemDescriptionsToArrayFormat(sysDescDict, keyMap);
70 if (sysDescArray == nil)
71 {
72 OOLog(@"sysdesc.compile.failed.conversion", @"%@", @"Could not convert sysdesc.plist to descriptions.plist format for some reason.");
73 return;
74 }
75
76 sysDescDict = [NSDictionary dictionaryWithObject:sysDescArray forKey:@"system_description"];
77
78 if (asXML)
79 {
80 data = [NSPropertyListSerialization dataFromPropertyList:sysDescDict
81 format:NSPropertyListXMLFormat_v1_0
82 errorDescription:&error];
83 }
84 else
85 {
86 data = [sysDescDict oldSchoolPListFormatWithErrorDescription:&error];
87 }
88
89 if (data == nil)
90 {
91 OOLog(@"sysdesc.compile.failed.XML", @"Could not convert translated sysdesc.plist to property list: %@.", error);
92 return;
93 }
94
95 if ([ResourceManager writeDiagnosticData:data toFileNamed:@"sysdesc-compiled.plist"])
96 {
97 OOLog(@"sysdesc.compile.success", @"%@", @"Wrote translated sysdesc.plist to sysdesc-compiled.plist.");
98 }
99 else
100 {
101 OOLog(@"sysdesc.compile.failed.writeFailure", @"%@", @"Could not write translated sysdesc.plist to sysdesc-compiled.plist.");
102 }
103}
104
105
107{
108 NSArray *sysDescArray = nil;
109 NSDictionary *sysDescDict = nil;
110 NSDictionary *keyMap = nil;
111 NSData *data = nil;
112 NSString *error = nil;
113
114 sysDescArray = [[UNIVERSE descriptions] oo_arrayForKey:@"system_description"];
115
116 keyMap = [ResourceManager dictionaryFromFilesNamed:@"sysdesc_key_table.plist"
117 inFolder:@"Config"
118 andMerge:NO];
119 // keyMap is optional, so no nil check
120
121 sysDescDict = OOConvertSystemDescriptionsToDictionaryFormat(sysDescArray, keyMap);
122 if (sysDescArray == nil)
123 {
124 OOLog(@"sysdesc.export.failed.conversion", @"%@", @"Could not convert system_description do sysdesc.plist format for some reason.");
125 return;
126 }
127
128 if (asXML)
129 {
130 data = [NSPropertyListSerialization dataFromPropertyList:sysDescDict
131 format:NSPropertyListXMLFormat_v1_0
132 errorDescription:&error];
133 }
134 else
135 {
136 data = [sysDescDict oldSchoolPListFormatWithErrorDescription:&error];
137 }
138
139 if (data == nil)
140 {
141 OOLog(@"sysdesc.export.failed.XML", @"Could not convert translated system_description to XML property list: %@.", error);
142 return;
143 }
144
145 if ([ResourceManager writeDiagnosticData:data toFileNamed:@"sysdesc.plist"])
146 {
147 OOLog(@"sysdesc.export.success", @"%@", @"Wrote translated system_description to sysdesc.plist.");
148 }
149 else
150 {
151 OOLog(@"sysdesc.export.failed.writeFailure", @"%@", @"Could not write translated system_description to sysdesc.plist.");
152 }
153}
154
155
156NSArray *OOConvertSystemDescriptionsToArrayFormat(NSDictionary *descriptionsInDictionaryFormat, NSDictionary *indicesToKeys)
157{
158 NSMutableDictionary *result = nil;
159 NSAutoreleasePool *pool = nil;
160 NSString *key = nil;
161 NSArray *entry = nil;
162 NSEnumerator *keyEnum = nil;
163 NSMutableDictionary *keysToIndices = nil;
164 NSMutableSet *usedIndices = nil;
165 NSUInteger slotCache = 0;
166 NSNumber *index = nil;
167 NSUInteger i, count;
168 NSMutableArray *realResult = nil;
169
170 pool = [[NSAutoreleasePool alloc] init];
171
172 // Use a dictionary as a sparse array.
173 result = [NSMutableDictionary dictionaryWithCapacity:[descriptionsInDictionaryFormat count]];
174
175 keysToIndices = InitKeyToIndexDict(indicesToKeys, &usedIndices);
176
177 for (keyEnum = [descriptionsInDictionaryFormat keyEnumerator]; (key = [keyEnum nextObject]); )
178 {
179 entry = ConvertKeysToIndices([descriptionsInDictionaryFormat objectForKey:key], keysToIndices, usedIndices, &slotCache);
180 index = KeyToIndex(key, keysToIndices, usedIndices, &slotCache);
181
182 [result setObject:entry forKey:index];
183 }
184
185 count = HighestIndex(result);
186 realResult = [NSMutableArray arrayWithCapacity:count];
187 for (i = 0; i < count; i++)
188 {
189 entry = [result objectForKey:[NSNumber numberWithUnsignedInteger:i]];
190 if (entry == nil) entry = [NSArray array];
191 [realResult addObject:entry];
192 }
193
194 [realResult retain];
195 [pool release];
196 return [realResult autorelease];
197}
198
199
200NSDictionary *OOConvertSystemDescriptionsToDictionaryFormat(NSArray *descriptionsInArrayFormat, NSDictionary *indicesToKeys)
201{
202 NSMutableDictionary *result = nil;
203 NSAutoreleasePool *pool = nil;
204 NSArray *entry = nil;
205 NSEnumerator *entryEnum = nil;
206 NSString *key = nil;
207 NSUInteger i = 0;
208
209 result = [NSMutableDictionary dictionaryWithCapacity:[descriptionsInArrayFormat count]];
210 pool = [[NSAutoreleasePool alloc] init];
211
212 for (entryEnum = [descriptionsInArrayFormat objectEnumerator]; (entry = [entryEnum nextObject]); )
213 {
214 entry = ConvertIndicesToKeys(entry, indicesToKeys);
215 key = IndexToKey(i, indicesToKeys, YES);
216 ++i;
217
218 [result setObject:entry forKey:key];
219 }
220
221 [pool release];
222 return result;
223}
224
225
226NSString *OOStringifySystemDescriptionLine(NSString *line, NSDictionary *indicesToKeys, BOOL useFallback)
227{
228 NSUInteger p1, p2;
229 NSRange searchRange;
230 NSString *before = nil, *after = nil, *middle = nil;
231 NSString *key = nil;
232
233 searchRange.location = 0;
234 searchRange.length = [line length];
235
236 while ([line rangeOfString:@"[" options:NSLiteralSearch range:searchRange].location != NSNotFound)
237 {
238 p1 = [line rangeOfString:@"[" options:NSLiteralSearch range:searchRange].location;
239 p2 = [line rangeOfString:@"]" options:NSLiteralSearch range:searchRange].location + 1;
240
241 before = [line substringWithRange:NSMakeRange(0, p1)];
242 after = [line substringWithRange:NSMakeRange(p2,[line length] - p2)];
243 middle = [line substringWithRange:NSMakeRange(p1 + 1 , p2 - p1 - 2)];
244
245 if ([[middle stringByTrimmingCharactersInSet:[NSCharacterSet characterSetWithCharactersInString:@"0123456789"]] isEqual:@""] && ![middle isEqual:@""])
246 {
247 // Found [] around integers only
248 key = IndexToKey([middle intValue], indicesToKeys, useFallback);
249 if (key != nil)
250 {
251 line = [NSString stringWithFormat:@"%@[#%@]%@", before, key, after];
252 }
253 }
254
255 searchRange.length -= p2 - searchRange.location;
256 searchRange.location = [line length] - searchRange.length;
257 }
258 return line;
259}
260
261
262static NSMutableDictionary *InitKeyToIndexDict(NSDictionary *dict, NSMutableSet **outUsedIndices)
263{
264 NSEnumerator *keyEnum = nil;
265 NSString *key = nil;
266 NSNumber *number = nil;
267 NSMutableDictionary *result = nil;
268 NSMutableSet *used = nil;
269
270 assert(outUsedIndices != NULL);
271
272 result = [NSMutableDictionary dictionaryWithCapacity:[dict count]];
273 used = [NSMutableSet setWithCapacity:[dict count]];
274
275 for (keyEnum = [dict keyEnumerator]; (key = [keyEnum nextObject]); )
276 {
277 // Convert keys of dict to array indices
278 number = [NSNumber numberWithInt:[key intValue]];
279 [result setObject:number forKey:[dict objectForKey:key]];
280 [used addObject:number];
281 }
282
283 *outUsedIndices = used;
284 return result;
285}
286
287
288static NSString *IndexToKey(NSUInteger index, NSDictionary *indicesToKeys, BOOL useFallback)
289{
290 NSString *result = [indicesToKeys objectForKey:[NSString stringWithFormat:@"%lu", index]];
291 if (result == nil && useFallback) result = [NSString stringWithFormat:@"block_%lu", index];
292
293 return result;
294}
295
296
297static NSArray *ConvertIndicesToKeys(NSArray *entry, NSDictionary *indicesToKeys)
298{
299 NSEnumerator *lineEnum = nil;
300 NSString *line = nil;
301 NSMutableArray *result = nil;
302
303 result = [NSMutableArray arrayWithCapacity:[entry count]];
304
305 for (lineEnum = [entry objectEnumerator]; (line = [lineEnum nextObject]); )
306 {
307 [result addObject:OOStringifySystemDescriptionLine(line, indicesToKeys, YES)];
308 }
309
310 return result;
311}
312
313
314static NSNumber *KeyToIndex(NSString *key, NSMutableDictionary *ioKeysToIndices, NSMutableSet *ioUsedIndicies, NSUInteger *ioSlotCache)
315{
316 NSNumber *result = nil;
317
318 assert(ioSlotCache != NULL);
319
320 result = [ioKeysToIndices objectForKey:key];
321 if (result == nil)
322 {
323 // Search for free index
324 do
325 {
326 result = [NSNumber numberWithUnsignedInteger:(*ioSlotCache)++];
327 }
328 while ([ioUsedIndicies containsObject:result]);
329
330 [ioKeysToIndices setObject:result forKey:key];
331 [ioUsedIndicies addObject:result];
332 OOLog(@"sysdesc.compile.unknownKey", @"Assigning key \"%@\" to index %@.", key, result);
333 }
334
335 return result;
336}
337
338
339static NSArray *ConvertKeysToIndices(NSArray *entry, NSMutableDictionary *ioKeysToIndices, NSMutableSet *ioUsedIndicies, NSUInteger *ioSlotCache)
340{
341 NSEnumerator *lineEnum = nil;
342 NSString *line = nil;
343 NSUInteger p1, p2;
344 NSRange searchRange;
345 NSMutableArray *result = nil;
346 NSString *before = nil, *after = nil, *middle = nil;
347
348 result = [NSMutableArray arrayWithCapacity:[entry count]];
349
350 for (lineEnum = [entry objectEnumerator]; (line = [lineEnum nextObject]); )
351 {
352 searchRange.location = 0;
353 searchRange.length = [line length];
354
355 while ([line rangeOfString:@"[" options:NSLiteralSearch range:searchRange].location != NSNotFound)
356 {
357 p1 = [line rangeOfString:@"[" options:NSLiteralSearch range:searchRange].location;
358 p2 = [line rangeOfString:@"]" options:NSLiteralSearch range:searchRange].location + 1;
359
360 before = [line substringWithRange:NSMakeRange(0, p1)];
361 after = [line substringWithRange:NSMakeRange(p2,[line length] - p2)];
362 middle = [line substringWithRange:NSMakeRange(p1 + 1 , p2 - p1 - 2)];
363
364 if ([middle length] > 1 && [middle hasPrefix:@"#"])
365 {
366 // Found [] around key
367 line = [NSString stringWithFormat:@"%@[%@]%@", before, KeyToIndex([middle substringFromIndex:1], ioKeysToIndices, ioUsedIndicies, ioSlotCache), after];
368 }
369
370 searchRange.length -= p2 - searchRange.location;
371 searchRange.location = [line length] - searchRange.length;
372 }
373
374 [result addObject:line];
375 }
376
377 return result;
378}
379
380
381static NSUInteger HighestIndex(NSMutableDictionary *sparseArray)
382{
383 NSEnumerator *keyEnum = nil;
384 NSNumber *key = nil;
385 NSUInteger curr, highest = 0;
386
387 for (keyEnum = [sparseArray keyEnumerator]; (key = [keyEnum nextObject]); )
388 {
389 curr = [key intValue];
390 if (highest < curr) highest = curr;
391 }
392
393 return highest;
394}
395
396#endif
static NSMutableDictionary * InitKeyToIndexDict(NSDictionary *dict, NSMutableSet **outUsedIndices)
static NSArray * ConvertKeysToIndices(NSArray *entry, NSMutableDictionary *ioKeysToIndices, NSMutableSet *ioUsedIndicies, NSUInteger *ioSlotCache)
static NSUInteger HighestIndex(NSMutableDictionary *sparseArray)
void CompileSystemDescriptions(BOOL asXML)
void ExportSystemDescriptions(BOOL asXML)
static NSNumber * KeyToIndex(NSString *key, NSMutableDictionary *ioKeysToIndices, NSMutableSet *ioUsedIndicies, NSUInteger *ioSlotCache)
static NSArray * ConvertIndicesToKeys(NSArray *entry, NSDictionary *indicesToKeys)
NSDictionary * OOConvertSystemDescriptionsToDictionaryFormat(NSArray *descriptionsInArrayFormat, NSDictionary *indicesToKeys)
NSString * OOStringifySystemDescriptionLine(NSString *line, NSDictionary *indicesToKeys, BOOL useFallback)
NSArray * OOConvertSystemDescriptionsToArrayFormat(NSDictionary *descriptionsInDictionaryFormat, NSDictionary *indicesToKeys)
static NSString * IndexToKey(NSUInteger index, NSDictionary *indicesToKeys, BOOL useFallback)
#define OOLog(class, format,...)
Definition OOLogging.h:88
unsigned count
return nil
NSDictionary * dictionaryFromFilesNamed:inFolder:andMerge:(NSString *fileName,[inFolder] NSString *folderName,[andMerge] BOOL mergeFiles)