remove po converter and support completely
parent
36f91cffd4
commit
d46844a817
|
@ -1,609 +0,0 @@
|
|||
/*
|
||||
* POConverter.m
|
||||
*
|
||||
* Created by Da Woon Jung on Wed March 09 2005.
|
||||
* Copyright (c) 2005 dwj. All rights reserved.
|
||||
*
|
||||
* 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 2
|
||||
* 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, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
|
||||
|
||||
#define POCONV_DEFAULT_STRINGS_FILENAME @"po.strings"
|
||||
#define POCONV_DEBUG_LEVEL 1
|
||||
|
||||
BOOL gIgnoreFuzzy; /*! -n cmdline arg, YES = ignore fuzzy entries */
|
||||
int gDebugLevel; /*! -v cmdline arg, 0 = no console messages */
|
||||
NSCharacterSet *gNewLineSet;
|
||||
NSCharacterSet *gDelimitSet;
|
||||
|
||||
|
||||
/*! Returns NO if line is a comment. range and result are modified. */
|
||||
static BOOL readLine(NSString *string, NSRange *range, NSString **outString)
|
||||
{
|
||||
// Using -lineRangeForRange: because it reliably detects all sorts of line endings
|
||||
NSRange lineRange = [string lineRangeForRange: *range];
|
||||
NSString *lineString = (NSNotFound != lineRange.location && lineRange.length > 0) ? [string substringWithRange: lineRange] : nil;
|
||||
range->location = NSMaxRange(lineRange);
|
||||
range->length = 0;
|
||||
*outString = lineString;
|
||||
|
||||
// Detect comment lines
|
||||
return lineString ? ![lineString hasPrefix: @"#"] : YES;
|
||||
}
|
||||
|
||||
|
||||
/*! Scans data (from a po file) in ascii mode and gets the charset specification */
|
||||
static NSStringEncoding getCharset(NSData *data)
|
||||
{
|
||||
NSString *string = [[NSString alloc] initWithData:data encoding:NSASCIIStringEncoding];
|
||||
if (nil == string)
|
||||
return 0;
|
||||
|
||||
CFStringEncoding enc = kCFStringEncodingUTF8;
|
||||
NSString *line = nil;
|
||||
NSString *encName = nil;
|
||||
NSRange encRange;
|
||||
NSRange range = NSMakeRange(0, 0);
|
||||
BOOL notComment = YES;
|
||||
|
||||
while (YES)
|
||||
{
|
||||
notComment = readLine(string, &range, &line);
|
||||
if (nil == line)
|
||||
break;
|
||||
|
||||
if (notComment)
|
||||
{
|
||||
encRange = [line rangeOfString: @"Content-Type:"];
|
||||
if (NSNotFound != encRange.location && encRange.length > 0)
|
||||
{
|
||||
encRange = [line rangeOfString: @"charset="];
|
||||
if (NSNotFound != encRange.location && encRange.length > 0)
|
||||
{
|
||||
encName = [line substringWithRange: NSMakeRange(NSMaxRange(encRange), [line length] - NSMaxRange(encRange))];
|
||||
if (encName)
|
||||
{
|
||||
encRange = [encName rangeOfString:@"\\n\"" options:NSBackwardsSearch];
|
||||
if (NSNotFound != encRange.location && encRange.location > 0 && encRange.length > 0)
|
||||
encName = [encName substringToIndex: encRange.location];
|
||||
|
||||
// Some special cases
|
||||
if (NSOrderedSame == [encName caseInsensitiveCompare:@"gbk"])
|
||||
enc = kCFStringEncodingGBK_95;
|
||||
else if (NSOrderedSame == [encName caseInsensitiveCompare:@"ISO_8859-15"])
|
||||
enc = kCFStringEncodingISOLatin9;
|
||||
else
|
||||
enc = CFStringConvertIANACharSetNameToEncoding((CFStringRef)encName);
|
||||
}
|
||||
|
||||
if (gDebugLevel)
|
||||
CFShow((__bridge CFTypeRef)(line));
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return (kCFStringEncodingInvalidId == enc) ? NSUTF8StringEncoding : CFStringConvertEncodingToNSStringEncoding(enc);
|
||||
}
|
||||
|
||||
|
||||
static NSString *extractStringFromLine(NSString *line)
|
||||
{
|
||||
NSMutableString *result = [NSMutableString stringWithCapacity: [line length]];
|
||||
NSString *aString;
|
||||
NSScanner *scanner = [NSScanner scannerWithString: line];
|
||||
NSRange escRange;
|
||||
NSMutableString *escString = [NSMutableString string];
|
||||
|
||||
while (![scanner isAtEnd])
|
||||
{
|
||||
aString = nil;
|
||||
|
||||
[scanner scanUpToString:@"\"" intoString: nil];
|
||||
if ([scanner scanString:@"\"" intoString: nil])
|
||||
{
|
||||
while (YES)
|
||||
{
|
||||
// Make sure we don't skip leading spaces (but skip newlines)
|
||||
NSCharacterSet *origSkip = [scanner charactersToBeSkipped];
|
||||
[scanner setCharactersToBeSkipped: gNewLineSet];
|
||||
[scanner scanUpToCharactersFromSet: gDelimitSet intoString: &aString];
|
||||
// Remove shorcut key ampersands
|
||||
// TODO: Recognize longer "(&x)" format used in
|
||||
// non-roman localizations
|
||||
while ([scanner scanString: @"&" intoString: nil])
|
||||
{
|
||||
if (aString)
|
||||
[escString appendString: aString];
|
||||
[scanner scanUpToCharactersFromSet: gDelimitSet intoString: &aString];
|
||||
}
|
||||
// [scanner scanUpToString:@"\"" intoString: &aString];
|
||||
[scanner setCharactersToBeSkipped: origSkip];
|
||||
|
||||
if (aString)
|
||||
{
|
||||
[escString appendString: aString];
|
||||
|
||||
escRange = [aString rangeOfString:@"\\" options:(NSBackwardsSearch|NSAnchoredSearch)];
|
||||
|
||||
if (NSNotFound != escRange.location && escRange.length > 0)
|
||||
{
|
||||
[scanner scanString:@"\"" intoString: &aString];
|
||||
[escString appendString: aString];
|
||||
aString = nil;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
aString = nil;
|
||||
break;
|
||||
}
|
||||
|
||||
if ([scanner scanString:@"\"" intoString: nil])
|
||||
{
|
||||
if (escString)
|
||||
[result appendString: escString];
|
||||
}
|
||||
}
|
||||
else
|
||||
break;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
/*! Get all parts of a quoted string (possibly broken across multiple lines) and returns the concatenated result. */
|
||||
static NSString *getQuotedString(NSString *fileString, NSRange *range, NSString *line)
|
||||
{
|
||||
NSMutableString *result = [NSMutableString stringWithString:extractStringFromLine(line)];
|
||||
NSString *aString;
|
||||
NSRange origRange;
|
||||
|
||||
// Loop until no more string parts found
|
||||
BOOL notComment = YES;
|
||||
while (YES)
|
||||
{
|
||||
origRange = *range;
|
||||
notComment = readLine(fileString, range, &line);
|
||||
if (nil == line || ([line length] == 0))
|
||||
break;
|
||||
|
||||
if (!notComment || [line hasPrefix: @"msgid"] || [line hasPrefix: @"msgstr"])
|
||||
{
|
||||
// Back up the cursor
|
||||
*range = origRange;
|
||||
break;
|
||||
}
|
||||
|
||||
aString = extractStringFromLine(line);
|
||||
[result appendString: aString];
|
||||
}
|
||||
|
||||
return ([result length] > 0) ? result : nil;
|
||||
}
|
||||
|
||||
|
||||
/*! Takes any comment line. If it is a flag line (starts with #, ) and contains the "fuzzy" flag, returns YES */
|
||||
static BOOL isFuzzy(NSString *line)
|
||||
{
|
||||
NSRange flagRange = [line rangeOfString:@"#," options:NSAnchoredSearch];
|
||||
if (NSNotFound != flagRange.location && flagRange.length > 0)
|
||||
{
|
||||
// Parse comma-delimited list of flags
|
||||
NSString *aString = [line substringWithRange: NSMakeRange(NSMaxRange(flagRange), [line length] - NSMaxRange(flagRange))];
|
||||
if (aString)
|
||||
{
|
||||
NSArray *flags;
|
||||
NSEnumerator *flagEnum;
|
||||
NSScanner *scanner;
|
||||
|
||||
flags = [aString componentsSeparatedByString: @","];
|
||||
flagEnum = [flags objectEnumerator];
|
||||
while ((aString = [flagEnum nextObject]))
|
||||
{
|
||||
scanner = [NSScanner scannerWithString: aString];
|
||||
if ([scanner scanString:@"fuzzy" intoString: nil])
|
||||
{
|
||||
// Check if fuzzy is the entire word
|
||||
if ([scanner isAtEnd])
|
||||
return YES;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return NO;
|
||||
}
|
||||
|
||||
#ifdef TARGET_CELESTIA
|
||||
/*! Celestia: Returns YES if the line contains source file entries */
|
||||
static BOOL isSource(NSString *line, BOOL *containsNonKde)
|
||||
{
|
||||
BOOL isSource = NO;
|
||||
|
||||
NSRange range = [line rangeOfString:@"#:" options:NSAnchoredSearch];
|
||||
if (NSNotFound != range.location && range.length > 0)
|
||||
{
|
||||
BOOL nonKdeFound = NO;
|
||||
BOOL kdeFound = NO;
|
||||
isSource = YES;
|
||||
|
||||
NSString *aString = [line substringWithRange: NSMakeRange(NSMaxRange(range), [line length] - NSMaxRange(range))];
|
||||
|
||||
if (aString)
|
||||
{
|
||||
NSArray *sources;
|
||||
NSEnumerator *sourceEnum;
|
||||
|
||||
sources = [aString componentsSeparatedByString: @" "];
|
||||
sourceEnum = [sources objectEnumerator];
|
||||
|
||||
while ((aString = [sourceEnum nextObject]))
|
||||
{
|
||||
if (0 == [aString length])
|
||||
continue;
|
||||
range = [aString rangeOfString: @"kde"];
|
||||
if (NSNotFound == range.location)
|
||||
{
|
||||
nonKdeFound = YES;
|
||||
break;
|
||||
}
|
||||
else if (range.length > 0)
|
||||
kdeFound = YES;
|
||||
}
|
||||
}
|
||||
|
||||
if (nonKdeFound || !kdeFound)
|
||||
*containsNonKde = YES;
|
||||
}
|
||||
|
||||
return isSource;
|
||||
}
|
||||
#endif /* TARGET_CELESTIA */
|
||||
|
||||
/*! Does all the work of reading, converting, and writing. Returns the number of lines successfully converted. */
|
||||
static long convertData(NSData *data, NSStringEncoding encoding, NSFileHandle *ofh)
|
||||
{
|
||||
long numConverted = 0;
|
||||
NSString *fileString = [[NSString alloc] initWithData:data encoding:encoding];
|
||||
if (nil == fileString)
|
||||
return 0;
|
||||
|
||||
BOOL notComment = YES;
|
||||
NSString *line;
|
||||
__strong NSString **aString;
|
||||
NSRange range = NSMakeRange(0, 0);
|
||||
long fileStringLength = [fileString length];
|
||||
|
||||
BOOL acceptEntry = YES;
|
||||
#ifdef TARGET_CELESTIA
|
||||
BOOL parsingSources = NO;
|
||||
BOOL containsNonKde = NO;
|
||||
#endif
|
||||
NSString *msgid = nil;
|
||||
NSString *msgstr = nil;
|
||||
|
||||
while (range.location < fileStringLength)
|
||||
{
|
||||
notComment = readLine(fileString, &range, &line);
|
||||
if (nil == line)
|
||||
break;
|
||||
|
||||
if (notComment)
|
||||
{
|
||||
aString = nil;
|
||||
|
||||
if ([line hasPrefix: @"msgid"])
|
||||
aString = &msgid;
|
||||
else if ([line hasPrefix: @"msgstr"])
|
||||
{
|
||||
if (nil == msgid)
|
||||
{
|
||||
if (gDebugLevel>2)
|
||||
CFShow(@"Ignoring msgstr without msgid (probably the po header)");
|
||||
continue;
|
||||
}
|
||||
aString = &msgstr;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Blank line cancels fuzzy flag
|
||||
acceptEntry = YES;
|
||||
}
|
||||
|
||||
#ifdef TARGET_CELESTIA
|
||||
// if (parsingSources)
|
||||
// acceptEntry = containsNonKde;
|
||||
acceptEntry = YES;
|
||||
parsingSources = NO;
|
||||
containsNonKde = NO;
|
||||
#endif
|
||||
if (aString)
|
||||
{
|
||||
*aString = getQuotedString(fileString, &range, line);
|
||||
|
||||
if (*aString == msgstr && msgid)
|
||||
{
|
||||
if (nil == *aString)
|
||||
{
|
||||
if (gDebugLevel>1)
|
||||
CFShow((CFStringRef)[NSString stringWithFormat:@"Ignoring msgid \"%@\" without msgstr", msgid]);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (acceptEntry)
|
||||
{
|
||||
NSString *ofhString = [NSString stringWithFormat:@"\"%@\" = \"%@\";\n", msgid, msgstr];
|
||||
if (ofhString)
|
||||
{
|
||||
NSData *ofhData;
|
||||
if (numConverted > 0)
|
||||
{
|
||||
size_t ofhBufSize = [ofhString length]*sizeof(unichar);
|
||||
unichar *ofhBuf = malloc(ofhBufSize);
|
||||
[ofhString getCharacters: ofhBuf]; // gets utf-16 chars
|
||||
ofhData = [NSData dataWithBytesNoCopy:ofhBuf length:ofhBufSize];
|
||||
}
|
||||
else
|
||||
{
|
||||
// Before overwriting an existing file, have to zero it
|
||||
if (ofh)
|
||||
[ofh truncateFileAtOffset: 0];
|
||||
|
||||
// Output bom for first entry
|
||||
ofhData = [ofhString dataUsingEncoding:NSUnicodeStringEncoding];
|
||||
}
|
||||
|
||||
[ofh writeData:ofhData];
|
||||
}
|
||||
else if (gDebugLevel)
|
||||
CFShow(@"***Couldn't write data***");
|
||||
|
||||
++numConverted;
|
||||
|
||||
if (gDebugLevel>2 && *aString)
|
||||
CFShow((__bridge CFTypeRef)(*aString));
|
||||
}
|
||||
else if (gDebugLevel)
|
||||
CFShow((CFStringRef)[NSString stringWithFormat:@"Ignoring entry \"%@\"", *aString]);
|
||||
|
||||
msgid = nil;
|
||||
msgstr = nil;
|
||||
acceptEntry = YES;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
#ifdef TARGET_CELESTIA
|
||||
// Celestia: filter out kde entries
|
||||
// This looks complicated, but is needed because
|
||||
// source entries (#:) may span multiple lines
|
||||
if (!parsingSources)
|
||||
{
|
||||
containsNonKde = NO;
|
||||
parsingSources = isSource(line, &containsNonKde);
|
||||
}
|
||||
else
|
||||
{
|
||||
BOOL tempKdeCheck = NO;
|
||||
if (isSource(line, &tempKdeCheck))
|
||||
containsNonKde = containsNonKde || tempKdeCheck;
|
||||
}
|
||||
#endif
|
||||
// Filter out fuzzy entries if specified by the caller
|
||||
if (gIgnoreFuzzy && isFuzzy(line))
|
||||
acceptEntry = NO;
|
||||
}
|
||||
}
|
||||
|
||||
return numConverted;
|
||||
}
|
||||
|
||||
|
||||
static void usage()
|
||||
{
|
||||
printf("Poconverter converts a GNU gettext po file to Mac OS-native\n"
|
||||
"UTF-16 Localized.strings format.\n"
|
||||
"\n"
|
||||
"Usage: Poconverter [-nv] file.po [destination filename]\n"
|
||||
"\n"
|
||||
" -n Ignore entries tagged with fuzzy flag\n"
|
||||
" -s Silent mode (existing file overwritten without warning)\n"
|
||||
" -v Verbose output on stderr\n"
|
||||
"\n");
|
||||
}
|
||||
|
||||
static void ctrl_c_handler(int sig)
|
||||
{
|
||||
fprintf(stderr, "\nGot Ctrl-C, cleaning up...\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
int main(int argc, const char **argv)
|
||||
{
|
||||
@autoreleasepool {
|
||||
// Catch ctrl-c so we can release the autorelease pool
|
||||
signal(SIGINT, ctrl_c_handler);
|
||||
|
||||
gIgnoreFuzzy = NO;
|
||||
gDebugLevel = 0;
|
||||
BOOL isSilent = NO;
|
||||
|
||||
BOOL isErr = NO;
|
||||
NSProcessInfo *theProcess = [NSProcessInfo processInfo];
|
||||
NSArray *args = [theProcess arguments];
|
||||
NSString *arg;
|
||||
NSEnumerator *argEnum = [args objectEnumerator];
|
||||
[argEnum nextObject]; // advance past args[0] (the program full path)
|
||||
|
||||
NSString *poFilename = nil;
|
||||
NSString *resultFilename = nil;
|
||||
NSFileHandle *ofh;
|
||||
|
||||
do
|
||||
{
|
||||
if (argc < 2 || argc > 5)
|
||||
{
|
||||
usage(); break;
|
||||
}
|
||||
|
||||
// Parse options
|
||||
long j;
|
||||
|
||||
while ((arg = [argEnum nextObject]) && [arg hasPrefix: @"-"])
|
||||
{
|
||||
if ([arg length] > 1)
|
||||
{
|
||||
for (j = 1; j < [arg length]; ++j)
|
||||
{
|
||||
switch ([arg characterAtIndex: j])
|
||||
{
|
||||
case 'n':
|
||||
gIgnoreFuzzy = YES; break;
|
||||
case 's':
|
||||
isSilent = YES; break;
|
||||
case 'v':
|
||||
gDebugLevel = POCONV_DEBUG_LEVEL; break;
|
||||
default:
|
||||
isErr = YES;
|
||||
}
|
||||
|
||||
if (isErr)
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
isErr = YES;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (isErr)
|
||||
{
|
||||
usage(); break;
|
||||
}
|
||||
|
||||
// Can't just have options, need filename(s) too
|
||||
if (nil == arg)//i == argc)
|
||||
{
|
||||
usage(); break;
|
||||
}
|
||||
|
||||
poFilename = arg;
|
||||
|
||||
// Check if po file exists and isn't a directory
|
||||
BOOL isDirectory;
|
||||
BOOL fileExists;
|
||||
NSFileManager *fm = [NSFileManager defaultManager];
|
||||
|
||||
if (![fm fileExistsAtPath:poFilename isDirectory:&isDirectory] || isDirectory)
|
||||
{
|
||||
usage(); break;
|
||||
}
|
||||
|
||||
// Destination path - can be either a filename or a directory
|
||||
// If unspecified, defaults to stdout
|
||||
resultFilename = [argEnum nextObject];
|
||||
|
||||
if (resultFilename)
|
||||
{
|
||||
if ([argEnum nextObject])
|
||||
{
|
||||
// Too many filenames
|
||||
usage(); break;
|
||||
}
|
||||
|
||||
// If directory, append default filename
|
||||
fileExists = [fm fileExistsAtPath:resultFilename isDirectory:&isDirectory];
|
||||
if (fileExists && isDirectory)
|
||||
{
|
||||
resultFilename = [resultFilename stringByAppendingPathComponent:POCONV_DEFAULT_STRINGS_FILENAME];
|
||||
fileExists = [fm fileExistsAtPath: resultFilename];
|
||||
}
|
||||
|
||||
if (!fileExists)
|
||||
{
|
||||
[fm createFileAtPath:resultFilename contents:nil attributes:nil];
|
||||
}
|
||||
|
||||
if(!isSilent && fileExists)
|
||||
{
|
||||
printf("\nDestination file exists, overwrite (y/n)? [y] ");
|
||||
int confirm = getchar();
|
||||
fflush(stdout);
|
||||
|
||||
switch (confirm)
|
||||
{
|
||||
case 'y':
|
||||
case 'Y':
|
||||
case '\n':
|
||||
break;
|
||||
default:
|
||||
printf("Destination file not overwritten.\n\n");
|
||||
exit(0);
|
||||
}
|
||||
}
|
||||
|
||||
ofh = [NSFileHandle fileHandleForWritingAtPath: resultFilename];
|
||||
// Delay truncating file and wiping it out until we actually
|
||||
// get something to write to
|
||||
}
|
||||
else
|
||||
{
|
||||
// Output filename not specified, use stdout
|
||||
ofh = [NSFileHandle fileHandleWithStandardOutput];
|
||||
}
|
||||
|
||||
if (nil == ofh)
|
||||
{
|
||||
CFShow(@"***Could not write output. Please check if directory exists, and you have permissions.***");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
if (gDebugLevel)
|
||||
CFShow((CFStringRef)[NSString stringWithFormat:@"poFile='%@', result='%@', ignoreFuzzy=%d, debugLevel=%d, silent=%d", poFilename, (resultFilename ? resultFilename : @"stdout"), gIgnoreFuzzy, gDebugLevel, isSilent]);
|
||||
|
||||
NSData *data = [NSData dataWithContentsOfMappedFile: poFilename];
|
||||
NSMutableCharacterSet *newLineSet = [[NSCharacterSet whitespaceAndNewlineCharacterSet] mutableCopy];
|
||||
[newLineSet formIntersectionWithCharacterSet:
|
||||
[[NSCharacterSet whitespaceCharacterSet] invertedSet]];
|
||||
gNewLineSet = newLineSet;
|
||||
gDelimitSet = [NSCharacterSet characterSetWithCharactersInString: @"&\""];
|
||||
|
||||
// First detect the file encoding
|
||||
NSStringEncoding encoding = getCharset(data);
|
||||
if (gDebugLevel)
|
||||
CFShow((CFStringRef)[NSString stringWithFormat:@"NSStringEncoding = %#lx", encoding]);
|
||||
|
||||
// Reread the file again, in the correct encoding
|
||||
long numConverted = 0;
|
||||
if (encoding)
|
||||
{
|
||||
numConverted = convertData(data, encoding, ofh);
|
||||
}
|
||||
|
||||
if (gDebugLevel)
|
||||
CFShow((CFStringRef)[NSString stringWithFormat:@"%ld entries converted.", numConverted]);
|
||||
} while (NO);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
|
@ -1,72 +0,0 @@
|
|||
/*
|
||||
* POSupport.cpp
|
||||
* Celestia
|
||||
*
|
||||
* Created by Da Woon Jung on 2008-01-13.
|
||||
* Copyright 2008 Da Woon Jung. All rights reserved.
|
||||
*
|
||||
* 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 2
|
||||
* 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, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
#include <CoreFoundation/CoreFoundation.h>
|
||||
#include "POSupport.h"
|
||||
#include <string>
|
||||
#include <map>
|
||||
#include <iostream>
|
||||
|
||||
#define LOCALIZED_STR_BUFSIZE 1024
|
||||
|
||||
typedef std::map<std::string, std::string> StringMap;
|
||||
typedef std::map<std::string, StringMap> MapMap;
|
||||
MapMap domainDict;
|
||||
|
||||
const char *localizedUTF8String(const char *key)
|
||||
{
|
||||
return localizedUTF8StringWithDomain("po", key);
|
||||
}
|
||||
|
||||
const char *localizedUTF8StringWithDomain(const char *domain, const char *key)
|
||||
{
|
||||
std::string domainStr(domain);
|
||||
std::string keyStr(key);
|
||||
MapMap::iterator iter = domainDict.find(domainStr);
|
||||
if (iter == domainDict.end())
|
||||
{
|
||||
StringMap strMap;
|
||||
domainDict[domainStr] = strMap;
|
||||
iter = domainDict.find(domainStr);
|
||||
}
|
||||
StringMap &localizedDict = iter->second;
|
||||
StringMap::iterator strIter = localizedDict.find(keyStr);
|
||||
if (strIter == localizedDict.end())
|
||||
{
|
||||
CFStringRef domainRef = CFStringCreateWithCStringNoCopy(NULL, domain, kCFStringEncodingUTF8, kCFAllocatorNull);
|
||||
CFStringRef keyRef = CFStringCreateWithCStringNoCopy(NULL, key, kCFStringEncodingUTF8, kCFAllocatorNull);
|
||||
CFStringRef localizedRef = CFCopyLocalizedStringFromTable(keyRef, domainRef, "");
|
||||
char localizedBuf[LOCALIZED_STR_BUFSIZE];
|
||||
CFStringGetCString(localizedRef, localizedBuf, LOCALIZED_STR_BUFSIZE, kCFStringEncodingUTF8);
|
||||
std::string localizedStr(localizedBuf);
|
||||
localizedDict[keyStr] = localizedStr;
|
||||
CFRelease(localizedRef);
|
||||
if (keyRef)
|
||||
{
|
||||
CFRelease(keyRef);
|
||||
}
|
||||
CFRelease(domainRef);
|
||||
strIter = localizedDict.find(keyStr);
|
||||
}
|
||||
std::string &localized = strIter->second;
|
||||
return localized.c_str();
|
||||
}
|
|
@ -1,29 +0,0 @@
|
|||
/*
|
||||
* POSupport.h
|
||||
* Celestia
|
||||
*
|
||||
* Created by Da Woon Jung on 3/14/05.
|
||||
* Copyright 2005 dwj. All rights reserved.
|
||||
*
|
||||
* 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 2
|
||||
* 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, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
*/
|
||||
|
||||
#ifndef _POSUPPORT_H_
|
||||
#define _POSUPPORT_H_
|
||||
|
||||
extern const char *localizedUTF8String(const char *key);
|
||||
extern const char *localizedUTF8StringWithDomain(const char *domain, const char *key);
|
||||
|
||||
#endif
|
|
@ -225,8 +225,6 @@
|
|||
E5A994770B1482FE009F40FA /* scriptobject.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E5A994730B1482FE009F40FA /* scriptobject.cpp */; };
|
||||
E5B48EBA0C22065E00C6FBD7 /* MacInputWatcher.mm in Sources */ = {isa = PBXBuildFile; fileRef = E5B48EB80C22065E00C6FBD7 /* MacInputWatcher.mm */; };
|
||||
E5C9ADE10848FFEF0071B1EE /* Carbon.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = F5040B0602A47B91014901DC /* Carbon.framework */; };
|
||||
E5CAABA70D3D7A08001926FC /* POSupport.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E5CAABA60D3D7A08001926FC /* POSupport.cpp */; };
|
||||
E5CC203709AA836E00CFFF2C /* POConverter.m in Sources */ = {isa = PBXBuildFile; fileRef = E5CC203209AA834B00CFFF2C /* POConverter.m */; };
|
||||
E5CC204709AA843300CFFF2C /* Localizable.strings in Resources */ = {isa = PBXBuildFile; fileRef = E5CC204509AA843300CFFF2C /* Localizable.strings */; };
|
||||
E5D3E6550D1EA18A00214838 /* axisarrow.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E5D3E6530D1EA18A00214838 /* axisarrow.cpp */; };
|
||||
E5D446660777291700A1577D /* utf8.cpp in Sources */ = {isa = PBXBuildFile; fileRef = E5D446640777291700A1577D /* utf8.cpp */; };
|
||||
|
@ -282,19 +280,8 @@
|
|||
FF7B2B1C0E89B23D0089BF43 /* galaxies.dsc in Copy Data */ = {isa = PBXBuildFile; fileRef = FF7B2B120E89B1A30089BF43 /* galaxies.dsc */; };
|
||||
FF7B2B1D0E89B23D0089BF43 /* globulars.dsc in Copy Data */ = {isa = PBXBuildFile; fileRef = FF7B2B130E89B1A30089BF43 /* globulars.dsc */; };
|
||||
FF7B2B220E89B3250089BF43 /* itokawa.cmod in Copy Models */ = {isa = PBXBuildFile; fileRef = FF7B2B210E89B2F20089BF43 /* itokawa.cmod */; };
|
||||
FFACF2C10E75F1BD007AE5CF /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 29B97325FDCFA39411CA2CEA /* Foundation.framework */; };
|
||||
/* End PBXBuildFile section */
|
||||
|
||||
/* Begin PBXContainerItemProxy section */
|
||||
E5CC205909AA8C7100CFFF2C /* PBXContainerItemProxy */ = {
|
||||
isa = PBXContainerItemProxy;
|
||||
containerPortal = 29B97313FDCFA39411CA2CEA /* Project object */;
|
||||
proxyType = 1;
|
||||
remoteGlobalIDString = E5CC202809AA823400CFFF2C;
|
||||
remoteInfo = POConverter;
|
||||
};
|
||||
/* End PBXContainerItemProxy section */
|
||||
|
||||
/* Begin PBXCopyFilesBuildPhase section */
|
||||
E567F018099110C000D05031 /* Copy Data */ = {
|
||||
isa = PBXCopyFilesBuildPhase;
|
||||
|
@ -668,10 +655,6 @@
|
|||
E5B61B2E077737A6001BB2BF /* png.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = png.h; path = include/png.h; sourceTree = "<group>"; };
|
||||
E5B61B2F077737A6001BB2BF /* pngconf.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = pngconf.h; path = include/pngconf.h; sourceTree = "<group>"; };
|
||||
E5C9B46B084909B90071B1EE /* README for Mac OS X.rtf */ = {isa = PBXFileReference; lastKnownFileType = text.rtf; path = "README for Mac OS X.rtf"; sourceTree = "<group>"; };
|
||||
E5CAABA60D3D7A08001926FC /* POSupport.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = POSupport.cpp; sourceTree = "<group>"; };
|
||||
E5CC202909AA823400CFFF2C /* POConverter */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = POConverter; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||
E5CC203209AA834B00CFFF2C /* POConverter.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = POConverter.m; sourceTree = "<group>"; };
|
||||
E5CC203309AA834B00CFFF2C /* POSupport.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = POSupport.h; sourceTree = "<group>"; };
|
||||
E5CC204809AA846600CFFF2C /* fr */ = {isa = PBXFileReference; fileEncoding = 10; lastKnownFileType = text.plist.strings; name = fr; path = fr.lproj/Localizable.strings; sourceTree = "<group>"; };
|
||||
E5D3E6530D1EA18A00214838 /* axisarrow.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = axisarrow.cpp; path = ../src/celengine/axisarrow.cpp; sourceTree = SOURCE_ROOT; };
|
||||
E5D3E6540D1EA18A00214838 /* axisarrow.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = axisarrow.h; path = ../src/celengine/axisarrow.h; sourceTree = SOURCE_ROOT; };
|
||||
|
@ -1016,14 +999,6 @@
|
|||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
FFACF2C00E75F1AE007AE5CF /* Frameworks */ = {
|
||||
isa = PBXFrameworksBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
FFACF2C10E75F1BD007AE5CF /* Foundation.framework in Frameworks */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
/* End PBXFrameworksBuildPhase section */
|
||||
|
||||
/* Begin PBXGroup section */
|
||||
|
@ -1070,7 +1045,6 @@
|
|||
9717E96D234B641E00AAD7D1 /* Migrator.m */,
|
||||
F578B79D02B3E2AD0100020A /* Cocoa Extensions */,
|
||||
F55A246702B2D4FF0100020A /* Wrappers */,
|
||||
E5CC203109AA832000CFFF2C /* POConverter */,
|
||||
);
|
||||
name = Classes;
|
||||
sourceTree = "<group>";
|
||||
|
@ -1101,7 +1075,6 @@
|
|||
isa = PBXGroup;
|
||||
children = (
|
||||
E564312E07769C9000E2C4A3 /* Celestia.app */,
|
||||
E5CC202909AA823400CFFF2C /* POConverter */,
|
||||
);
|
||||
name = Products;
|
||||
sourceTree = "<group>";
|
||||
|
@ -1281,16 +1254,6 @@
|
|||
path = ../extras;
|
||||
sourceTree = SOURCE_ROOT;
|
||||
};
|
||||
E5CC203109AA832000CFFF2C /* POConverter */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
E5CC203209AA834B00CFFF2C /* POConverter.m */,
|
||||
E5CC203309AA834B00CFFF2C /* POSupport.h */,
|
||||
E5CAABA60D3D7A08001926FC /* POSupport.cpp */,
|
||||
);
|
||||
name = POConverter;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
E5D766250982B3300099DBBD /* models */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
|
@ -1795,7 +1758,6 @@
|
|||
buildRules = (
|
||||
);
|
||||
dependencies = (
|
||||
E5CC205A09AA8C7100CFFF2C /* PBXTargetDependency */,
|
||||
);
|
||||
name = Celestia;
|
||||
productInstallPath = "$(HOME)/Applications";
|
||||
|
@ -1803,22 +1765,6 @@
|
|||
productReference = E564312E07769C9000E2C4A3 /* Celestia.app */;
|
||||
productType = "com.apple.product-type.application";
|
||||
};
|
||||
E5CC202809AA823400CFFF2C /* POConverter */ = {
|
||||
isa = PBXNativeTarget;
|
||||
buildConfigurationList = E5CC202B09AA829B00CFFF2C /* Build configuration list for PBXNativeTarget "POConverter" */;
|
||||
buildPhases = (
|
||||
E5CC202609AA823400CFFF2C /* Sources */,
|
||||
FFACF2C00E75F1AE007AE5CF /* Frameworks */,
|
||||
);
|
||||
buildRules = (
|
||||
);
|
||||
dependencies = (
|
||||
);
|
||||
name = POConverter;
|
||||
productName = POConverter;
|
||||
productReference = E5CC202909AA823400CFFF2C /* POConverter */;
|
||||
productType = "com.apple.product-type.tool";
|
||||
};
|
||||
/* End PBXNativeTarget section */
|
||||
|
||||
/* Begin PBXProject section */
|
||||
|
@ -1853,7 +1799,6 @@
|
|||
projectRoot = "";
|
||||
targets = (
|
||||
E564302B07769C9000E2C4A3 /* Celestia */,
|
||||
E5CC202809AA823400CFFF2C /* POConverter */,
|
||||
);
|
||||
};
|
||||
/* End PBXProject section */
|
||||
|
@ -2060,7 +2005,6 @@
|
|||
E512245A0CF9FC7D009092A2 /* BrowserItem.mm in Sources */,
|
||||
E5D542770D0B87EA00E8C513 /* Menu_Extensions.mm in Sources */,
|
||||
E5D3E6550D1EA18A00214838 /* axisarrow.cpp in Sources */,
|
||||
E5CAABA70D3D7A08001926FC /* POSupport.cpp in Sources */,
|
||||
8844B87E0D5AA3290059AA3A /* customrotation.cpp in Sources */,
|
||||
8844BAAE0D6D13FE0059AA3A /* frametree.cpp in Sources */,
|
||||
8844BAB00D6D13FE0059AA3A /* timeline.cpp in Sources */,
|
||||
|
@ -2088,24 +2032,8 @@
|
|||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
E5CC202609AA823400CFFF2C /* Sources */ = {
|
||||
isa = PBXSourcesBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
E5CC203709AA836E00CFFF2C /* POConverter.m in Sources */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
/* End PBXSourcesBuildPhase section */
|
||||
|
||||
/* Begin PBXTargetDependency section */
|
||||
E5CC205A09AA8C7100CFFF2C /* PBXTargetDependency */ = {
|
||||
isa = PBXTargetDependency;
|
||||
target = E5CC202809AA823400CFFF2C /* POConverter */;
|
||||
targetProxy = E5CC205909AA8C7100CFFF2C /* PBXContainerItemProxy */;
|
||||
};
|
||||
/* End PBXTargetDependency section */
|
||||
|
||||
/* Begin PBXVariantGroup section */
|
||||
089C165CFE840E0CC02AAC07 /* InfoPlist.strings */ = {
|
||||
isa = PBXVariantGroup;
|
||||
|
@ -2410,90 +2338,6 @@
|
|||
};
|
||||
name = Development;
|
||||
};
|
||||
E5CC202C09AA829B00CFFF2C /* Development */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
buildSettings = {
|
||||
ALWAYS_SEARCH_USER_PATHS = NO;
|
||||
CLANG_ENABLE_OBJC_ARC = YES;
|
||||
CODE_SIGN_IDENTITY = "-";
|
||||
COPY_PHASE_STRIP = NO;
|
||||
GCC_PREPROCESSOR_DEFINITIONS = (
|
||||
"$(GCC_PREPROCESSOR_DEFINITIONS)",
|
||||
TARGET_CELESTIA,
|
||||
);
|
||||
INSTALL_PATH = "$(HOME)/bin";
|
||||
PRODUCT_NAME = POConverter;
|
||||
SKIP_INSTALL = YES;
|
||||
ZERO_LINK = NO;
|
||||
};
|
||||
name = Development;
|
||||
};
|
||||
E5CC202E09AA829B00CFFF2C /* Universal_Release */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
buildSettings = {
|
||||
ALWAYS_SEARCH_USER_PATHS = NO;
|
||||
CLANG_ENABLE_OBJC_ARC = YES;
|
||||
CODE_SIGN_IDENTITY = "-";
|
||||
COPY_PHASE_STRIP = NO;
|
||||
GCC_PREPROCESSOR_DEFINITIONS = (
|
||||
"$(GCC_PREPROCESSOR_DEFINITIONS)",
|
||||
TARGET_CELESTIA,
|
||||
);
|
||||
INSTALL_PATH = "$(HOME)/bin";
|
||||
OTHER_LDFLAGS = (
|
||||
"-framework",
|
||||
Foundation,
|
||||
);
|
||||
PRODUCT_NAME = POConverter;
|
||||
SKIP_INSTALL = YES;
|
||||
ZERO_LINK = NO;
|
||||
};
|
||||
name = Universal_Release;
|
||||
};
|
||||
E5F9EC660D9EA6BE00A83FEF /* HDR_Development */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
buildSettings = {
|
||||
ALWAYS_SEARCH_USER_PATHS = NO;
|
||||
CLANG_ENABLE_OBJC_ARC = YES;
|
||||
CODE_SIGN_IDENTITY = "-";
|
||||
COPY_PHASE_STRIP = NO;
|
||||
GCC_PREPROCESSOR_DEFINITIONS = (
|
||||
"$(GCC_PREPROCESSOR_DEFINITIONS)",
|
||||
TARGET_CELESTIA,
|
||||
);
|
||||
INSTALL_PATH = "$(HOME)/bin";
|
||||
OTHER_LDFLAGS = (
|
||||
"-framework",
|
||||
Foundation,
|
||||
);
|
||||
PRODUCT_NAME = POConverter;
|
||||
SKIP_INSTALL = YES;
|
||||
ZERO_LINK = NO;
|
||||
};
|
||||
name = HDR_Development;
|
||||
};
|
||||
E5F9EC670D9EA6BE00A83FEF /* HDR_Universal_Release */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
buildSettings = {
|
||||
ALWAYS_SEARCH_USER_PATHS = NO;
|
||||
CLANG_ENABLE_OBJC_ARC = YES;
|
||||
CODE_SIGN_IDENTITY = "-";
|
||||
COPY_PHASE_STRIP = NO;
|
||||
GCC_PREPROCESSOR_DEFINITIONS = (
|
||||
"$(GCC_PREPROCESSOR_DEFINITIONS)",
|
||||
TARGET_CELESTIA,
|
||||
);
|
||||
INSTALL_PATH = "$(HOME)/bin";
|
||||
OTHER_LDFLAGS = (
|
||||
"-framework",
|
||||
Foundation,
|
||||
);
|
||||
PRODUCT_NAME = POConverter;
|
||||
SKIP_INSTALL = YES;
|
||||
ZERO_LINK = NO;
|
||||
};
|
||||
name = HDR_Universal_Release;
|
||||
};
|
||||
E5F9EC680D9EA6BE00A83FEF /* HDR_Development */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
buildSettings = {
|
||||
|
@ -2716,17 +2560,6 @@
|
|||
defaultConfigurationIsVisible = 0;
|
||||
defaultConfigurationName = Universal_Release;
|
||||
};
|
||||
E5CC202B09AA829B00CFFF2C /* Build configuration list for PBXNativeTarget "POConverter" */ = {
|
||||
isa = XCConfigurationList;
|
||||
buildConfigurations = (
|
||||
E5CC202C09AA829B00CFFF2C /* Development */,
|
||||
E5F9EC660D9EA6BE00A83FEF /* HDR_Development */,
|
||||
E5CC202E09AA829B00CFFF2C /* Universal_Release */,
|
||||
E5F9EC670D9EA6BE00A83FEF /* HDR_Universal_Release */,
|
||||
);
|
||||
defaultConfigurationIsVisible = 0;
|
||||
defaultConfigurationName = Universal_Release;
|
||||
};
|
||||
/* End XCConfigurationList section */
|
||||
};
|
||||
rootObject = 29B97313FDCFA39411CA2CEA /* Project object */;
|
||||
|
|
Loading…
Reference in New Issue