adium 3598:26c935192629: Move the scandate function (this versio...

commits at adium.im commits at adium.im
Sun Dec 19 20:16:37 UTC 2010


details:	http://hg.adium.im/adium/rev/26c935192629
revision:	3598:26c935192629
author:		Peter Hosey <hg at boredzo.org>
date:		Sat Dec 18 22:17:28 2010 -0800

Move the scandate function (this version of it, at least) into a separate pair of files and make a test case for it*. Currently, all 7 tests fail.

*Based on https://twitter.com/edr1084/status/16306394684727296 .
(transplanted from de5dde2df90ba961c6845ef69e9b2b4249c3cce1)
Subject: adium 3599:5ac06e388d8e: Corrected this comment.

details:	http://hg.adium.im/adium/rev/5ac06e388d8e
revision:	3599:5ac06e388d8e
author:		Peter Hosey <hg at boredzo.org>
date:		Sat Dec 18 22:18:28 2010 -0800

Corrected this comment.
(transplanted from 58a99313cd1bf1ca6a2e6079491b7c4fa355ff06)
Subject: adium 3600:dad10cff1d97: Documented what scandate is looking for in the input string.

details:	http://hg.adium.im/adium/rev/dad10cff1d97
revision:	3600:dad10cff1d97
author:		Peter Hosey <hg at boredzo.org>
date:		Sat Dec 18 22:19:05 2010 -0800

Documented what scandate is looking for in the input string.
(transplanted from 81824cc5c596c761b3fd5659b2fb6c6d15b1b7e4)
Subject: adium 3601:702cc85890dc: Fixed detection of the date by looking for the last open parenthesis, not the first. Down to one failure.

details:	http://hg.adium.im/adium/rev/702cc85890dc
revision:	3601:702cc85890dc
author:		Peter Hosey <hg at boredzo.org>
date:		Sat Dec 18 22:20:38 2010 -0800

Fixed detection of the date by looking for the last open parenthesis, not the first. Down to one failure.
(transplanted from 0ee6ce1cf4d5061de8c3a6e291330b3849f7a614)
Subject: adium 3602:d753b073bc8c: Fixed a wrong value in the test case - this should be negative five hours, not positive five hours. All tests now pass.

details:	http://hg.adium.im/adium/rev/d753b073bc8c
revision:	3602:d753b073bc8c
author:		Peter Hosey <hg at boredzo.org>
date:		Sat Dec 18 22:21:40 2010 -0800

Fixed a wrong value in the test case - this should be negative five hours, not positive five hours. All tests now pass.
(transplanted from e20de4ece2464a8f2f0750c26f3f1226cbb7fd9f)
Subject: adium 3603:b030b3188719: Added a prefix header for the Spotlight importer.

details:	http://hg.adium.im/adium/rev/b030b3188719
revision:	3603:b030b3188719
author:		Peter Hosey <hg at boredzo.org>
date:		Sat Dec 18 23:08:38 2010 -0800

Added a prefix header for the Spotlight importer.
(transplanted from b678f1bfdb70ea2a3a465dcc13571eabc3075af7)
Subject: adium 3604:c071ac69695f: Deleted the other copy of scandate from the Spotlight Importer. Include and link the one that [de5dde2df90b] moved into a separate pair of files instead.

details:	http://hg.adium.im/adium/rev/c071ac69695f
revision:	3604:c071ac69695f
author:		Peter Hosey <hg at boredzo.org>
date:		Sat Dec 18 23:10:30 2010 -0800

Deleted the other copy of scandate from the Spotlight Importer. Include and link the one that [de5dde2df90b] moved into a separate pair of files instead.
(transplanted from 6fdac63920655de6345b86e659a858e43b0693a7)

diffs (634 lines):

diff -r 9c632c5abd01 -r c071ac69695f Adium.xcodeproj/project.pbxproj
--- a/Adium.xcodeproj/project.pbxproj	Sat Dec 18 21:53:31 2010 -0800
+++ b/Adium.xcodeproj/project.pbxproj	Sat Dec 18 23:10:30 2010 -0800
@@ -235,6 +235,8 @@
 		318EA69C0D7A659900EDB105 /* TestColorAdditions.m in Sources */ = {isa = PBXBuildFile; fileRef = 318EA69B0D7A659900EDB105 /* TestColorAdditions.m */; };
 		319B29800CE8EC6F00C65398 /* TestDateAdditions.m in Sources */ = {isa = PBXBuildFile; fileRef = 319B297F0CE8EC6E00C65398 /* TestDateAdditions.m */; };
 		31A764B90DA572B8000AC729 /* AutoHyperlinks.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 3496A8EA07CE6CA30055BBAB /* AutoHyperlinks.framework */; };
+		31DDDA7112BDD5CE0048F6C0 /* scandate.m in Sources */ = {isa = PBXBuildFile; fileRef = 31DDDA6F12BDD5CE0048F6C0 /* scandate.m */; };
+		31DDDA7A12BDD6E90048F6C0 /* TestScandate.m in Sources */ = {isa = PBXBuildFile; fileRef = 31DDDA7912BDD6E90048F6C0 /* TestScandate.m */; };
 		31E0CD810C5EEF5200271DB1 /* CoreAudio.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 31E0CD800C5EEF5200271DB1 /* CoreAudio.framework */; };
 		31FA804C0D4A8EB200ABE634 /* Adium.sdef in Resources */ = {isa = PBXBuildFile; fileRef = 0CAC6A130C0C657A0090AE95 /* Adium.sdef */; };
 		3402D5A5080DBC91004E50B4 /* SortConfiguration.nib in Resources */ = {isa = PBXBuildFile; fileRef = 347E791D07CAA52300350507 /* SortConfiguration.nib */; };
@@ -1150,6 +1152,8 @@
 		5A1781860EC1215D00BA1E04 /* AIAutoScrollTextView.m in Sources */ = {isa = PBXBuildFile; fileRef = 5A1781850EC1215D00BA1E04 /* AIAutoScrollTextView.m */; };
 		5A5F601D12962EC0007A2232 /* AISegmentedControl.m in Sources */ = {isa = PBXBuildFile; fileRef = 5A5F601A12962D06007A2232 /* AISegmentedControl.m */; };
 		5A5F601E12962ECE007A2232 /* AISegmentedControl.h in Headers */ = {isa = PBXBuildFile; fileRef = 5A5F601912962D06007A2232 /* AISegmentedControl.h */; settings = {ATTRIBUTES = (Public, ); }; };
+		5A804FEA12BE9E84007CDC1B /* scandate.m in Sources */ = {isa = PBXBuildFile; fileRef = 31DDDA6F12BDD5CE0048F6C0 /* scandate.m */; };
+		5A80508512BE9F00007CDC1B /* scandate.m in Sources */ = {isa = PBXBuildFile; fileRef = 31DDDA6F12BDD5CE0048F6C0 /* scandate.m */; };
 		5A94397B1279ECB800FDD81D /* AIImgurImageUploader.m in Sources */ = {isa = PBXBuildFile; fileRef = 5A94397A1279ECB800FDD81D /* AIImgurImageUploader.m */; };
 		5A9A9F8911F2951400328DF9 /* AIDoNothingContactAlertPlugin.m in Sources */ = {isa = PBXBuildFile; fileRef = 5A9A9F8811F2951400328DF9 /* AIDoNothingContactAlertPlugin.m */; };
 		5A9A9F8B11F295EB00328DF9 /* Stop sign.png in Resources */ = {isa = PBXBuildFile; fileRef = 5A9A9F8A11F295EB00328DF9 /* Stop sign.png */; };
@@ -2124,6 +2128,11 @@
 		318EA69B0D7A659900EDB105 /* TestColorAdditions.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = TestColorAdditions.m; path = UnitTests/TestColorAdditions.m; sourceTree = "<group>"; };
 		319B29420CE8D28300C65398 /* TestDateAdditions.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = TestDateAdditions.h; path = UnitTests/TestDateAdditions.h; sourceTree = "<group>"; };
 		319B297F0CE8EC6E00C65398 /* TestDateAdditions.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = TestDateAdditions.m; path = UnitTests/TestDateAdditions.m; sourceTree = "<group>"; };
+		31DDDA6E12BDD5CE0048F6C0 /* scandate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = scandate.h; path = Source/scandate.h; sourceTree = "<group>"; };
+		31DDDA6F12BDD5CE0048F6C0 /* scandate.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = scandate.m; path = Source/scandate.m; sourceTree = "<group>"; };
+		31DDDA7812BDD6E90048F6C0 /* TestScandate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = TestScandate.h; path = UnitTests/TestScandate.h; sourceTree = "<group>"; };
+		31DDDA7912BDD6E90048F6C0 /* TestScandate.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = TestScandate.m; path = UnitTests/TestScandate.m; sourceTree = "<group>"; };
+		31DDDAF112BDE54B0048F6C0 /* Prefix.pch */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = Prefix.pch; path = "Other/Adium Spotlight Importer/Prefix.pch"; sourceTree = "<group>"; };
 		31E0CD800C5EEF5200271DB1 /* CoreAudio.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreAudio.framework; path = /System/Library/Frameworks/CoreAudio.framework; sourceTree = "<absolute>"; };
 		31E84DF10C7F387800674BCA /* AIUnitTestUtilities.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = AIUnitTestUtilities.h; path = UnitTests/AIUnitTestUtilities.h; sourceTree = "<group>"; };
 		31FA7F0F0D4A75D000ABE634 /* TestRichTextCoercion.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = TestRichTextCoercion.h; path = UnitTests/TestRichTextCoercion.h; sourceTree = "<group>"; };
@@ -5270,6 +5279,8 @@
 				29B97323FDCFA39411CA2CEA /* Linked Frameworks */,
 				63C7E0280FAF9B7D00B310AC /* xcconfigs */,
 				19C28FACFE9D520D11CA2CBB /* Products */,
+				31DDDA7812BDD6E90048F6C0 /* TestScandate.h */,
+				31DDDA7912BDD6E90048F6C0 /* TestScandate.m */,
 			);
 			name = CocAIMe2;
 			sourceTree = "<group>";
@@ -7410,6 +7421,8 @@
 				349B359E0A5F2231008BE092 /* Views and Cells */,
 				3456231F0A3771E100E7FC97 /* AIChatLog.h */,
 				3456231E0A3771E100E7FC97 /* AIChatLog.m */,
+				31DDDA6E12BDD5CE0048F6C0 /* scandate.h */,
+				31DDDA6F12BDD5CE0048F6C0 /* scandate.m */,
 				345623250A3771F400E7FC97 /* AILogToGroup.h */,
 				345623240A3771F300E7FC97 /* AILogToGroup.m */,
 				345623270A3771F400E7FC97 /* AILogFromGroup.h */,
@@ -8224,6 +8237,7 @@
 				633D50550F9D31B8004F491E /* AdiumSpotlightImporter.h */,
 				633D4FB40F9D30E3004F491E /* main.c */,
 				633D4FB50F9D30E3004F491E /* maintest.m */,
+				31DDDAF112BDE54B0048F6C0 /* Prefix.pch */,
 				633D4FAF0F9D30E3004F491E /* Log Importing */,
 				633D4FAC0F9D30E3004F491E /* Additions */,
 			);
@@ -9585,7 +9599,6 @@
 			};
 			buildConfigurationList = DADE8E3A085507450062B664 /* Build configuration list for PBXProject "Adium" */;
 			compatibilityVersion = "Xcode 3.1";
-			developmentRegion = English;
 			hasScannedForEncodings = 1;
 			knownRegions = (
 				en,
@@ -10240,6 +10253,8 @@
 				318EA69C0D7A659900EDB105 /* TestColorAdditions.m in Sources */,
 				634BCD1F0DDC1542005AF1C2 /* TestMutableStringAdditions.m in Sources */,
 				3107D5250F63134F0051DDD5 /* TestAttributedStringAdditions.m in Sources */,
+				31DDDA7112BDD5CE0048F6C0 /* scandate.m in Sources */,
+				31DDDA7A12BDD6E90048F6C0 /* TestScandate.m in Sources */,
 			);
 			runOnlyForDeploymentPostprocessing = 0;
 		};
@@ -10728,6 +10743,7 @@
 				76C1AF9C125A906A00D269A9 /* AIAdiumURLProtocol.m in Sources */,
 				5A94397B1279ECB800FDD81D /* AIImgurImageUploader.m in Sources */,
 				349062A2127F7E6900FC313F /* AITemporaryIRCAccountWindowController.m in Sources */,
+				5A80508512BE9F00007CDC1B /* scandate.m in Sources */,
 			);
 			runOnlyForDeploymentPostprocessing = 0;
 		};
@@ -10946,6 +10962,7 @@
 				633D4FB80F9D30E3004F491E /* GetMetadataForHTMLLog.m in Sources */,
 				633D4FB90F9D30E3004F491E /* main.c in Sources */,
 				633D4FBE0F9D30FA004F491E /* NSCalendarDate+ISO8601Parsing.m in Sources */,
+				5A804FEA12BE9E84007CDC1B /* scandate.m in Sources */,
 			);
 			runOnlyForDeploymentPostprocessing = 0;
 		};
@@ -12723,6 +12740,8 @@
 			isa = XCBuildConfiguration;
 			baseConfigurationReference = 63C7E2080FAFAA4700B310AC /* Spotlight Importer.xcconfig */;
 			buildSettings = {
+				GCC_PRECOMPILE_PREFIX_HEADER = YES;
+				GCC_PREFIX_HEADER = "$(SRCROOT)/Other/Adium Spotlight Importer/Prefix.pch";
 			};
 			name = Debug;
 		};
@@ -12780,6 +12799,8 @@
 					"$(inherited)",
 					"\"$(SRCROOT)/Frameworks\"",
 				);
+				GCC_PRECOMPILE_PREFIX_HEADER = YES;
+				GCC_PREFIX_HEADER = "$(SRCROOT)/Other/Adium Spotlight Importer/Prefix.pch";
 			};
 			name = Release;
 		};
@@ -12791,6 +12812,8 @@
 					"$(inherited)",
 					"\"$(SRCROOT)/Frameworks\"",
 				);
+				GCC_PRECOMPILE_PREFIX_HEADER = YES;
+				GCC_PREFIX_HEADER = "$(SRCROOT)/Other/Adium Spotlight Importer/Prefix.pch";
 			};
 			name = "Release-Debug";
 		};
diff -r 9c632c5abd01 -r c071ac69695f Other/Adium Spotlight Importer/GetMetadataForHTMLLog.m
--- a/Other/Adium Spotlight Importer/GetMetadataForHTMLLog.m	Sat Dec 18 21:53:31 2010 -0800
+++ b/Other/Adium Spotlight Importer/GetMetadataForHTMLLog.m	Sat Dec 18 23:10:30 2010 -0800
@@ -10,90 +10,31 @@
 
 #include <sys/stat.h>
 
+#import "scandate.h"
+
 static char *gaim_markup_strip_html(const char *str);
 
-//Scan an Adium date string, supahfast C style
-static BOOL scandate(const char *sample, unsigned long *outyear,
-					 unsigned long *outmonth, unsigned long *outdate)
-{
-	BOOL success = YES;
-	unsigned long component;
-    //read three numbers, starting after:
-	
-	//a space...
-	while (*sample != ' ') {
-    	if (!*sample) {
-    		success = NO;
-    		goto fail;
-		} else {
-			++sample;
-		}
-    }
-	
-	//...followed by a (
-	while (*sample != '(') {
-    	if (!*sample) {
-    		success = NO;
-    		goto fail;
-		} else {
-			++sample;
-		}
-    }
-	
-	//current character is a '(' now, so skip over it.
-    ++sample; //start with the next character
-	
-    /*get the year*/ {
-		while (*sample && (*sample < '0' || *sample > '9')) ++sample;
-		if (!*sample) {
-			success = NO;
-			goto fail;
-		}
-		component = strtoul(sample, (char **)&sample, 10);
-		if (outyear) *outyear = component;
-    }
-    
-    /*get the month*/ {
-		while (*sample && (*sample < '0' || *sample > '9')) ++sample;
-		if (!*sample) {
-			success = NO;
-			goto fail;
-		}
-		component = strtoul(sample, (char **)&sample, 10);
-		if (outmonth) *outmonth = component;
-    }
-    
-    /*get the date*/ {
-		while (*sample && (*sample < '0' || *sample > '9')) ++sample;
-		if (!*sample) {
-			success = NO;
-			goto fail;
-		}
-		component = strtoul(sample, (char **)&sample, 10);
-		if (outdate) *outdate = component;
-    }
-	
-fail:
-		return success;
-}
-
-//Given an Adium log file name, return an NSCalendarDate with year, month, and day specified
+//Given an Adium log file name, return an NSCalendarDate for its creation date
 static NSDate *dateFromHTMLLog(NSString *pathToFile)
 {
 	NSDate *date = nil;
 	unsigned long   year = 0;
 	unsigned long   month = 0;
 	unsigned long   day = 0;
-	
-	if (scandate([pathToFile UTF8String], &year, &month, &day)) {
+	unsigned long   hour = 0;
+	unsigned long   minute = 0;
+	unsigned long   second = 0;
+	long   timeZoneOffset = +0;
+
+	if (scandate([pathToFile UTF8String], &year, &month, &day, /*outHasTime*/ NULL, &hour, &minute, &second, &timeZoneOffset)) {
 		if (year && month && day) {
 			NSCalendarDate *calendarDate = [NSCalendarDate dateWithYear:year
 																  month:month
 																	day:day
-																   hour:0
-																 minute:0
-																 second:0
-															   timeZone:[NSTimeZone defaultTimeZone]];
+																   hour:hour
+																 minute:minute
+																 second:second
+															   timeZone:[NSTimeZone timeZoneForSecondsFromGMT:(NSInteger)timeZoneOffset]];
 			date = [NSDate dateWithTimeIntervalSince1970:[calendarDate timeIntervalSince1970]];
 		}
 	}
diff -r 9c632c5abd01 -r c071ac69695f Other/Adium Spotlight Importer/Prefix.pch
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Other/Adium Spotlight Importer/Prefix.pch	Sat Dec 18 23:10:30 2010 -0800
@@ -0,0 +1,8 @@
+#if __OBJC__
+#	import <Cocoa/Cocoa.h>
+#endif
+
+#import <CoreFoundation/CoreFoundation.h>
+#import <CoreFoundation/CFPlugInCOM.h>
+#import <CoreServices/CoreServices.h>
+#import <ApplicationServices/ApplicationServices.h>
diff -r 9c632c5abd01 -r c071ac69695f Source/AIChatLog.m
--- a/Source/AIChatLog.m	Sat Dec 18 21:53:31 2010 -0800
+++ b/Source/AIChatLog.m	Sat Dec 18 23:10:30 2010 -0800
@@ -21,6 +21,7 @@
 #import "AICalendarDate.h"
 
 #import <AIUtilities/NSCalendarDate+ISO8601Parsing.h>
+#import "scandate.h"
 
 @implementation AIChatLog
 
@@ -306,134 +307,6 @@
 
 #pragma mark Date utilities
 
-//Scan an Adium date string, supahfast C style
-static BOOL scandate(const char *sample,
-					 unsigned long *outyear, unsigned long *outmonth,  unsigned long *outdate,
-					 BOOL *outHasTime, unsigned long *outhour, unsigned long *outminute, unsigned long *outsecond,
-					 long *outtimezone)
-{
-	BOOL success = YES;
-	unsigned long component;
-
-    //Read a date, followed by a '('.
-	//First, find the '('.
-	while (*sample != '(') {
-    	if (!*sample) {
-    		success = NO;
-    		goto fail;
-		} else {
-			++sample;
-		}
-    }
-	
-	//current character is a '(' now, so skip over it.
-    ++sample; //start with the next character
-	
-    /*get the year*/ {
-		while (*sample && (*sample < '0' || *sample > '9')) ++sample;
-		if (!*sample) {
-			success = NO;
-			goto fail;
-		}
-		component = strtoul(sample, (char **)&sample, 10);
-		if (outyear) *outyear = component;
-    }
-    
-    /*get the month*/ {
-		while (*sample && (*sample < '0' || *sample > '9')) ++sample;
-		if (!*sample) {
-			success = NO;
-			goto fail;
-		}
-		component = strtoul(sample, (char **)&sample, 10);
-		if (outmonth) *outmonth = component;
-    }
-    
-    /*get the date*/ {
-		while (*sample && (*sample < '0' || *sample > '9')) ++sample;
-		if (!*sample) {
-			success = NO;
-			goto fail;
-		}
-		component = strtoul(sample, (char **)&sample, 10);
-		if (outdate) *outdate = component;
-    }
-
-    if (*sample == 'T') {
-		++sample; //start with the next character
-		if (outHasTime) *outHasTime = YES;
-		
-		/*get the hour*/ {
-			while (*sample && (*sample < '0' || *sample > '9')) ++sample;
-			if (!*sample) {
-				success = NO;
-				goto fail;
-			}
-			component = strtoul(sample, (char **)&sample, 10);
-			if (outhour) *outhour = component;
-		}
-
-		/*get the minute*/ {
-			while (*sample && (*sample < '0' || *sample > '9')) ++sample;
-			if (!*sample) {
-				success = NO;
-				goto fail;
-			}
-			component = strtoul(sample, (char **)&sample, 10);
-			if (outminute) *outminute = component;
-		}
-
-		/*get the second*/ {
-			while (*sample && (*sample < '0' || *sample > '9')) ++sample;
-			if (!*sample) {
-				success = NO;
-				goto fail;
-			}
-			component = strtoul(sample, (char **)&sample, 10);
-			if (outsecond) *outsecond = component;
-		}
-
-		/*get the time zone*/ {
-			while (*sample && ((*sample < '0' || *sample > '9') && *sample != '-' && *sample != '+')) ++sample;
-			if (!*sample) {
-				success = NO;
-				goto fail;
-			}
-			long timezone_sign = 1;
-			if(*sample == '+') {
-				++sample;
-			} else if(*sample == '-') {
-				timezone_sign = -1;
-				++sample;
-			} else if (*sample) {
-				//There's something here, but it's not a time zone. Bail.
-				success = NO;
-				goto fail;
-			}
-			long timezone_hr = 0;
-			if (*sample >= '0' || *sample <= '9') {
-				timezone_hr += *(sample++) - '0';
-			}
-			if (*sample >= '0' || *sample <= '9') {
-				timezone_hr *= 10;
-				timezone_hr += *(sample++) - '0';
-			}
-			long timezone_min = 0;
-			if (*sample >= '0' || *sample <= '9') {
-				timezone_min += *(sample++) - '0';
-			}
-			if (*sample >= '0' || *sample <= '9') {
-				timezone_min *= 10;
-				timezone_min += *(sample++) - '0';
-			}
-			if (outtimezone) *outtimezone = (timezone_hr * 60 + timezone_min) * timezone_sign;
-		}
-	}
-	
-fail:
-	return success;
-}
-
 //Given an Adium log file name, return an NSCalendarDate with year, month, and day specified
 static NSCalendarDate *dateFromFileName(NSString *fileName)
 {
diff -r 9c632c5abd01 -r c071ac69695f Source/scandate.h
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Source/scandate.h	Sat Dec 18 23:10:30 2010 -0800
@@ -0,0 +1,28 @@
+/* 
+ * Adium is the legal property of its developers, whose names are listed in the copyright file included
+ * with this source distribution.
+ * 
+ * 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.
+ */
+
+/*Input: A string in UTF-8 encoding containing an ISO 8601 date within a parenthesis.
+ *Output:
+ *- Year, month, and date
+ *- Whether time was found
+ *- The hour, minute, and second of that time
+ *- The time zone offset as a single number of minutes
+ *- (Return value) Whether a date was found.
+ */
+BOOL scandate(const char *sample,
+              unsigned long *outyear, unsigned long *outmonth,  unsigned long *outdate,
+              BOOL *outHasTime, unsigned long *outhour, unsigned long *outminute, unsigned long *outsecond,
+              long *outtimezone);
diff -r 9c632c5abd01 -r c071ac69695f Source/scandate.m
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Source/scandate.m	Sat Dec 18 23:10:30 2010 -0800
@@ -0,0 +1,149 @@
+/* 
+ * Adium is the legal property of its developers, whose names are listed in the copyright file included
+ * with this source distribution.
+ * 
+ * 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 "scandate.h"
+
+BOOL scandate(const char *sample,
+					 unsigned long *outyear, unsigned long *outmonth,  unsigned long *outdate,
+					 BOOL *outHasTime, unsigned long *outhour, unsigned long *outminute, unsigned long *outsecond,
+					 long *outtimezone)
+{
+	BOOL success = YES;
+	unsigned long component;
+
+	const char *lastOpenParenthesis = NULL;
+
+    //Read a '(', followed by a date.
+	//First, find the '('.
+	while (*sample != '\0') {
+		if (*sample == '(')
+			lastOpenParenthesis = sample;
+		++sample;
+    }
+
+	if (!lastOpenParenthesis) {
+		success = NO;
+		goto fail;
+	}
+	sample = lastOpenParenthesis;
+
+	//current character is a '(' now, so skip over it.
+    ++sample; //start with the next character
+	
+    /*get the year*/ {
+		while (*sample && (*sample < '0' || *sample > '9')) ++sample;
+		if (!*sample) {
+			success = NO;
+			goto fail;
+		}
+		component = strtoul(sample, (char **)&sample, 10);
+		if (outyear) *outyear = component;
+    }
+    
+    /*get the month*/ {
+		while (*sample && (*sample < '0' || *sample > '9')) ++sample;
+		if (!*sample) {
+			success = NO;
+			goto fail;
+		}
+		component = strtoul(sample, (char **)&sample, 10);
+		if (outmonth) *outmonth = component;
+    }
+    
+    /*get the date*/ {
+		while (*sample && (*sample < '0' || *sample > '9')) ++sample;
+		if (!*sample) {
+			success = NO;
+			goto fail;
+		}
+		component = strtoul(sample, (char **)&sample, 10);
+		if (outdate) *outdate = component;
+    }
+
+    if (*sample == 'T') {
+		++sample; //start with the next character
+		if (outHasTime) *outHasTime = YES;
+		
+		/*get the hour*/ {
+			while (*sample && (*sample < '0' || *sample > '9')) ++sample;
+			if (!*sample) {
+				success = NO;
+				goto fail;
+			}
+			component = strtoul(sample, (char **)&sample, 10);
+			if (outhour) *outhour = component;
+		}
+
+		/*get the minute*/ {
+			while (*sample && (*sample < '0' || *sample > '9')) ++sample;
+			if (!*sample) {
+				success = NO;
+				goto fail;
+			}
+			component = strtoul(sample, (char **)&sample, 10);
+			if (outminute) *outminute = component;
+		}
+
+		/*get the second*/ {
+			while (*sample && (*sample < '0' || *sample > '9')) ++sample;
+			if (!*sample) {
+				success = NO;
+				goto fail;
+			}
+			component = strtoul(sample, (char **)&sample, 10);
+			if (outsecond) *outsecond = component;
+		}
+
+		/*get the time zone*/ {
+			while (*sample && ((*sample < '0' || *sample > '9') && *sample != '-' && *sample != '+')) ++sample;
+			if (!*sample) {
+				success = NO;
+				goto fail;
+			}
+			long timezone_sign = 1;
+			if(*sample == '+') {
+				++sample;
+			} else if(*sample == '-') {
+				timezone_sign = -1;
+				++sample;
+			} else if (*sample) {
+				//There's something here, but it's not a time zone. Bail.
+				success = NO;
+				goto fail;
+			}
+			long timezone_hr = 0;
+			if (*sample >= '0' || *sample <= '9') {
+				timezone_hr += *(sample++) - '0';
+			}
+			if (*sample >= '0' || *sample <= '9') {
+				timezone_hr *= 10;
+				timezone_hr += *(sample++) - '0';
+			}
+			long timezone_min = 0;
+			if (*sample >= '0' || *sample <= '9') {
+				timezone_min += *(sample++) - '0';
+			}
+			if (*sample >= '0' || *sample <= '9') {
+				timezone_min *= 10;
+				timezone_min += *(sample++) - '0';
+			}
+			if (outtimezone) *outtimezone = (timezone_hr * 60 + timezone_min) * timezone_sign;
+		}
+	}
+	
+fail:
+	return success;
+}
diff -r 9c632c5abd01 -r c071ac69695f UnitTests/TestScandate.h
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/UnitTests/TestScandate.h	Sat Dec 18 23:10:30 2010 -0800
@@ -0,0 +1,17 @@
+//
+//  TestScandate.h
+//  Adium
+//
+//  Created by Peter Hosey on 2010-12-18.
+//  Copyright 2010 Peter Hosey. All rights reserved.
+//
+
+#import <Cocoa/Cocoa.h>
+#import <SenTestingKit/SenTestingKit.h>
+
+ at interface TestScandate : SenTestCase
+{}
+
+- (void) testEricRichiesTwitterTimelineLogFilename;
+
+ at end
diff -r 9c632c5abd01 -r c071ac69695f UnitTests/TestScandate.m
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/UnitTests/TestScandate.m	Sat Dec 18 23:10:30 2010 -0800
@@ -0,0 +1,40 @@
+//
+//  TestScandate.m
+//  Adium
+//
+//  Created by Peter Hosey on 2010-12-18.
+//  Copyright 2010 Peter Hosey. All rights reserved.
+//
+
+#import "TestScandate.h"
+
+#import "scandate.h"
+
+ at implementation TestScandate
+
+- (void) testEricRichiesTwitterTimelineLogFilename {
+	static const char EricRichiesTwitterTimelineLogFilename[] = "timeline (edr1084) (2010-12-18T17.42.58-0500).chatlog";
+	unsigned long correctYear = 2010, correctMonth = 12, correctDayOfMonth = 18;
+	BOOL correctDidFindTime = YES;
+	unsigned long correctHour = 17, correctMinute = 42, correctSecond = 58;
+	long correctTimeZoneOffsetInMinutes = -(5 * 60);
+	BOOL correctDidFindDate = YES;
+
+	unsigned long foundYear, foundMonth, foundDayOfMonth;
+	BOOL didFindTime;
+	unsigned long foundHour, foundMinute, foundSecond;
+	long foundTimeZoneOffsetInMinutes;
+
+	BOOL didFindDate = scandate(EricRichiesTwitterTimelineLogFilename, &foundYear, &foundMonth, &foundDayOfMonth, &didFindTime, &foundHour, &foundMinute, &foundSecond, &foundTimeZoneOffsetInMinutes);
+	STAssertEquals(didFindDate, correctDidFindDate, @"No date found in this string! '%s'", EricRichiesTwitterTimelineLogFilename);
+	STAssertEquals(foundYear, correctYear, @"Wrong year found in '%s'", EricRichiesTwitterTimelineLogFilename);
+	STAssertEquals(foundMonth, correctMonth, @"Wrong month found in '%s'", EricRichiesTwitterTimelineLogFilename);
+	STAssertEquals(foundDayOfMonth, correctDayOfMonth, @"Wrong day-of-month found in '%s'", EricRichiesTwitterTimelineLogFilename);
+	STAssertEquals(didFindTime, correctDidFindTime, @"No time found in this string! '%s'", EricRichiesTwitterTimelineLogFilename);
+	STAssertEquals(foundHour, correctHour, @"Wrong hour found in '%s'", EricRichiesTwitterTimelineLogFilename);
+	STAssertEquals(foundMinute, correctMinute, @"Wrong minute found in '%s'", EricRichiesTwitterTimelineLogFilename);
+	STAssertEquals(foundSecond, correctSecond, @"Wrong second found in '%s'", EricRichiesTwitterTimelineLogFilename);
+	STAssertEquals(foundTimeZoneOffsetInMinutes, correctTimeZoneOffsetInMinutes, @"Wrong time zone offset found in '%s'", EricRichiesTwitterTimelineLogFilename);
+}
+
+ at end




More information about the commits mailing list