2007-01-31 18:11:29 +01:00
|
|
|
/*
|
|
|
|
Copyright (C) 2005 Helge Hess
|
|
|
|
|
|
|
|
This file is part of SOPE.
|
|
|
|
|
|
|
|
SOPE is free software; you can redistribute it and/or modify it under
|
|
|
|
the terms of the GNU Lesser General Public License as published by the
|
|
|
|
Free Software Foundation; either version 2, or (at your option) any
|
|
|
|
later version.
|
|
|
|
|
|
|
|
SOPE 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 Lesser General Public
|
|
|
|
License for more details.
|
|
|
|
|
|
|
|
You should have received a copy of the GNU Lesser General Public
|
|
|
|
License along with SOPE; see the file COPYING. If not, write to the
|
|
|
|
Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA
|
|
|
|
02111-1307, USA.
|
|
|
|
*/
|
|
|
|
|
|
|
|
// Note: this does not yet produce valid XML output
|
|
|
|
|
|
|
|
|
|
|
|
@interface vcf2xml : NSObject
|
|
|
|
{
|
|
|
|
id<NSObject,SaxXMLReader> parser;
|
|
|
|
id sax;
|
|
|
|
}
|
|
|
|
|
|
|
|
- (int)runWithArguments:(NSArray *)_args;
|
|
|
|
|
|
|
|
@end
|
|
|
|
|
|
|
|
|
|
|
|
@interface MySAXHandler : SaxDefaultHandler
|
|
|
|
{
|
|
|
|
id locator;
|
|
|
|
int indent;
|
|
|
|
|
|
|
|
NSString *lastNS;
|
|
|
|
}
|
|
|
|
|
|
|
|
- (void)indent;
|
|
|
|
|
|
|
|
@end
|
|
|
|
|
|
|
|
@implementation vcf2xml
|
|
|
|
|
|
|
|
- (id)init {
|
|
|
|
if ((self = [super init]) != nil) {
|
|
|
|
self->parser = [[[SaxXMLReaderFactory standardXMLReaderFactory]
|
|
|
|
createXMLReaderForMimeType:@"text/x-vcard"] retain];
|
|
|
|
if (parser == nil) {
|
|
|
|
fprintf(stderr, "Error: could not load a vCard SAX driver bundle!\n");
|
|
|
|
exit(2);
|
|
|
|
}
|
|
|
|
//NSLog(@"Using parser: %@", self->parser);
|
|
|
|
|
|
|
|
self->sax = [[MySAXHandler alloc] init];
|
|
|
|
[parser setContentHandler:self->sax];
|
|
|
|
[parser setErrorHandler:self->sax];
|
|
|
|
}
|
|
|
|
return self;
|
|
|
|
}
|
|
|
|
|
|
|
|
- (void)dealloc {
|
|
|
|
[self->sax release];
|
|
|
|
[self->parser release];
|
|
|
|
[super dealloc];
|
|
|
|
}
|
|
|
|
|
|
|
|
/* process files */
|
|
|
|
|
|
|
|
- (void)processFile:(NSString *)_path {
|
|
|
|
[self->parser parseFromSystemId:_path];
|
|
|
|
}
|
|
|
|
|
|
|
|
/* error handling */
|
|
|
|
|
|
|
|
- (NSException *)handleException:(NSException *)_exc onPath:(NSString *)_p {
|
|
|
|
fprintf(stderr, "Error: catched exception on path '%s': %s\n",
|
|
|
|
[_p cString], [[_exc description] cString]);
|
|
|
|
return nil;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* main entry */
|
|
|
|
|
|
|
|
- (int)runWithArguments:(NSArray *)_args {
|
|
|
|
NSEnumerator *args;
|
|
|
|
NSString *arg;
|
|
|
|
|
|
|
|
/* begin processing */
|
|
|
|
|
|
|
|
args = [_args objectEnumerator];
|
|
|
|
[args nextObject]; // skip tool name ...
|
|
|
|
|
|
|
|
while ((arg = [args nextObject]) != nil) {
|
|
|
|
NSAutoreleasePool *pool2;
|
|
|
|
|
|
|
|
if ([arg hasPrefix:@"-"]) { /* consume defaults */
|
|
|
|
[args nextObject];
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
|
|
|
pool2 = [[NSAutoreleasePool alloc] init];
|
|
|
|
|
|
|
|
|
|
|
|
if (![arg isAbsolutePath]) {
|
|
|
|
arg = [[[NSFileManager defaultManager] currentDirectoryPath]
|
|
|
|
stringByAppendingPathComponent:arg];
|
|
|
|
}
|
|
|
|
|
|
|
|
NS_DURING
|
|
|
|
[self->parser parseFromSystemId:arg];
|
|
|
|
NS_HANDLER
|
|
|
|
[[self handleException:localException onPath:arg] raise];
|
|
|
|
NS_ENDHANDLER;
|
|
|
|
|
|
|
|
[pool2 release];
|
|
|
|
}
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
@end /* vcf2xml */
|
|
|
|
|
|
|
|
|
|
|
|
@implementation MySAXHandler
|
|
|
|
|
|
|
|
- (void)dealloc {
|
|
|
|
[self->lastNS release];
|
|
|
|
[self->locator release];
|
|
|
|
[super dealloc];
|
|
|
|
}
|
|
|
|
|
|
|
|
/* output */
|
|
|
|
|
|
|
|
- (void)indent {
|
|
|
|
int i;
|
|
|
|
|
|
|
|
for (i = 0; i < (self->indent * 4); i++)
|
|
|
|
fputc(' ', stdout);
|
|
|
|
}
|
|
|
|
|
|
|
|
/* documents */
|
|
|
|
|
|
|
|
- (void)setDocumentLocator:(id<NSObject,SaxLocator>)_loc {
|
|
|
|
[self->locator autorelease];
|
|
|
|
self->locator = [_loc retain];
|
|
|
|
}
|
|
|
|
|
|
|
|
- (void)startDocument {
|
|
|
|
//puts("start document ..");
|
|
|
|
//self->indent++;
|
|
|
|
}
|
|
|
|
- (void)endDocument {
|
|
|
|
//self->indent--;
|
|
|
|
//puts("end document.");
|
|
|
|
}
|
|
|
|
|
|
|
|
- (void)startPrefixMapping:(NSString *)_prefix uri:(NSString *)_uri {
|
|
|
|
[self indent];
|
|
|
|
//printf("ns-map: %s=%s\n", [_prefix cString], [_uri cString]);
|
|
|
|
}
|
|
|
|
- (void)endPrefixMapping:(NSString *)_prefix {
|
|
|
|
[self indent];
|
|
|
|
//printf("ns-unmap: %s\n", [_prefix cString]);
|
|
|
|
}
|
|
|
|
|
|
|
|
- (void)startElement:(NSString *)_localName
|
|
|
|
namespace:(NSString *)_ns
|
|
|
|
rawName:(NSString *)_rawName
|
|
|
|
attributes:(id<SaxAttributes>)_attrs
|
|
|
|
{
|
|
|
|
int i, c;
|
|
|
|
[self indent];
|
|
|
|
printf("<%s", [_localName cString]);
|
|
|
|
|
|
|
|
if ([_ns length] > 0) {
|
|
|
|
if ([_ns isEqualToString:self->lastNS])
|
|
|
|
;
|
|
|
|
else {
|
|
|
|
printf(" xmlns='%s'", [_ns cString]);
|
|
|
|
ASSIGNCOPY(self->lastNS, _ns);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
for (i = 0, c = [_attrs count]; i < c; i++) {
|
|
|
|
NSString *type;
|
|
|
|
NSString *ans;
|
|
|
|
|
|
|
|
ans = [_attrs uriAtIndex:i];
|
|
|
|
|
|
|
|
printf(" %s=\"%s\"",
|
|
|
|
[[_attrs nameAtIndex:i] cString],
|
|
|
|
[[_attrs valueAtIndex:i] cString]);
|
|
|
|
|
|
|
|
if (![_ns isEqualToString:ans])
|
|
|
|
printf("(ns=%s)", [ans cString]);
|
|
|
|
|
|
|
|
type = [_attrs typeAtIndex:i];
|
|
|
|
if (![type isEqualToString:@"CDATA"] && (type != nil))
|
|
|
|
printf("[%s]", [type cString]);
|
|
|
|
}
|
|
|
|
puts(">");
|
|
|
|
self->indent++;
|
|
|
|
}
|
|
|
|
- (void)endElement:(NSString *)_localName
|
|
|
|
namespace:(NSString *)_ns
|
|
|
|
rawName:(NSString *)_rawName
|
|
|
|
{
|
|
|
|
self->indent--;
|
|
|
|
[self indent];
|
|
|
|
printf("</%s>\n", [_localName cString]);
|
|
|
|
}
|
|
|
|
|
2014-06-16 21:30:26 +02:00
|
|
|
- (void)characters:(unichar *)_chars length:(NSUInteger)_len {
|
2007-01-31 18:11:29 +01:00
|
|
|
NSString *str;
|
|
|
|
id tmp;
|
2014-06-16 21:30:26 +02:00
|
|
|
NSUInteger i, len;
|
2007-01-31 18:11:29 +01:00
|
|
|
|
|
|
|
if (_len == 0) {
|
|
|
|
[self indent];
|
|
|
|
printf("\"\"\n");
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2014-06-16 21:30:26 +02:00
|
|
|
for (i = 0; i < _len; i++) {
|
2007-01-31 18:11:29 +01:00
|
|
|
if (_chars[i] > 255) {
|
|
|
|
NSLog(@"detected large char: o%04o d%03i h%04X",
|
|
|
|
_chars[i], _chars[i], _chars[i]);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
str = [NSString stringWithCharacters:_chars length:_len];
|
|
|
|
len = [str length];
|
|
|
|
|
|
|
|
tmp = [str componentsSeparatedByString:@"\n"];
|
|
|
|
str = [tmp componentsJoinedByString:@"\\n"];
|
|
|
|
tmp = [str componentsSeparatedByString:@"\r"];
|
|
|
|
str = [tmp componentsJoinedByString:@"\\r"];
|
|
|
|
|
|
|
|
[self indent];
|
|
|
|
printf("\"%s\"\n", [str cString]);
|
|
|
|
}
|
2014-06-16 21:30:26 +02:00
|
|
|
- (void)ignorableWhitespace:(unichar *)_chars length:(NSUInteger)_len {
|
2007-01-31 18:11:29 +01:00
|
|
|
NSString *data;
|
|
|
|
id tmp;
|
|
|
|
|
|
|
|
data = [NSString stringWithCharacters:_chars length:_len];
|
|
|
|
tmp = [data componentsSeparatedByString:@"\n"];
|
|
|
|
data = [tmp componentsJoinedByString:@"\\n"];
|
|
|
|
tmp = [data componentsSeparatedByString:@"\r"];
|
|
|
|
data = [tmp componentsJoinedByString:@"\\r"];
|
|
|
|
|
|
|
|
[self indent];
|
|
|
|
printf("whitespace: \"%s\"\n", [data cString]);
|
|
|
|
}
|
|
|
|
|
|
|
|
- (void)processingInstruction:(NSString *)_pi data:(NSString *)_data {
|
|
|
|
[self indent];
|
|
|
|
printf("PI: '%s' '%s'\n", [_pi cString], [_data cString]);
|
|
|
|
}
|
|
|
|
|
|
|
|
#if 0
|
|
|
|
- (xmlEntityPtr)getEntity:(NSString *)_name {
|
|
|
|
NSLog(@"get entity %@", _name);
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
- (xmlEntityPtr)getParameterEntity:(NSString *)_name {
|
|
|
|
NSLog(@"get para entity %@", _name);
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
|
|
|
/* entities */
|
|
|
|
|
|
|
|
- (id)resolveEntityWithPublicId:(NSString *)_pubId
|
|
|
|
systemId:(NSString *)_sysId
|
|
|
|
{
|
|
|
|
[self indent];
|
|
|
|
printf("shall resolve entity with '%s' '%s'",
|
|
|
|
[_pubId cString], [_sysId cString]);
|
|
|
|
return nil;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* errors */
|
|
|
|
|
|
|
|
- (void)warning:(SaxParseException *)_exception {
|
|
|
|
NSLog(@"warning(%@:%i): %@",
|
|
|
|
[[_exception userInfo] objectForKey:@"publicId"],
|
|
|
|
[[[_exception userInfo] objectForKey:@"line"] intValue],
|
|
|
|
[_exception reason]);
|
|
|
|
}
|
|
|
|
|
|
|
|
- (void)error:(SaxParseException *)_exception {
|
|
|
|
NSLog(@"error(%@:%i): %@",
|
|
|
|
[[_exception userInfo] objectForKey:@"publicId"],
|
|
|
|
[[[_exception userInfo] objectForKey:@"line"] intValue],
|
|
|
|
[_exception reason]);
|
|
|
|
}
|
|
|
|
|
|
|
|
- (void)fatalError:(SaxParseException *)_exception {
|
|
|
|
NSLog(@"fatal error(%@:%i): %@",
|
|
|
|
[[_exception userInfo] objectForKey:@"publicId"],
|
|
|
|
[[[_exception userInfo] objectForKey:@"line"] intValue],
|
|
|
|
[_exception reason]);
|
|
|
|
[_exception raise];
|
|
|
|
}
|
|
|
|
|
|
|
|
@end /* MySAXHandler */
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
int main(int argc, char **argv, char **env) {
|
|
|
|
NSAutoreleasePool *pool;
|
|
|
|
vcf2xml *tool;
|
|
|
|
int rc;
|
|
|
|
|
|
|
|
pool = [[NSAutoreleasePool alloc] init];
|
|
|
|
#if LIB_FOUNDATION_LIBRARY
|
|
|
|
[NSProcessInfo initializeWithArguments:argv count:argc environment:env];
|
|
|
|
#endif
|
|
|
|
|
|
|
|
if ((tool = [[vcf2xml alloc] init])) {
|
|
|
|
NS_DURING
|
|
|
|
rc = [tool runWithArguments:[[NSProcessInfo processInfo] arguments]];
|
|
|
|
NS_HANDLER
|
|
|
|
abort();
|
|
|
|
NS_ENDHANDLER;
|
|
|
|
|
|
|
|
[tool release];
|
|
|
|
}
|
|
|
|
else
|
|
|
|
rc = 1;
|
|
|
|
|
|
|
|
[pool release];
|
|
|
|
return rc;
|
|
|
|
}
|