source: trunk/Cocoa/Pester/Source/ParseDate.m@ 636

Last change on this file since 636 was 617, checked in by Nicholas Riley, 15 years ago

Don't die if Date::Manip fails to parse a date.

File size: 2.6 KB
RevLine 
[367]1//
2// ParseDate.m
3// Pester
4//
5// Created by Nicholas Riley on 11/28/07.
6// Copyright 2007 Nicholas Riley. All rights reserved.
7//
8
9#import <Foundation/Foundation.h>
10
11// generated by perl -MExtUtils::Embed -e xsinit -- -o perlxsi.c
12#include <EXTERN.h>
13#include <perl.h>
14
15EXTERN_C void xs_init (pTHX);
16
17EXTERN_C void boot_DynaLoader (pTHX_ CV* cv);
18
19EXTERN_C void
20xs_init(pTHX)
21{
22 char *file = __FILE__;
23 dXSUB_SYS;
24
25 /* DynaLoader is a special case */
26 newXS("DynaLoader::boot_DynaLoader", boot_DynaLoader, file);
27}
28// end generated code
29
30static PerlInterpreter *my_perl;
31static NSDateFormatter *dateManipFormatter;
32
33NSDate *parse_natural_language_date(NSString *input) {
34 if (my_perl == NULL) return nil;
35
36 if ([input rangeOfString: @"|"].length > 0) {
37 NSMutableString *sanitized = [[input mutableCopy] autorelease];
38 [sanitized replaceOccurrencesOfString: @"|" withString: @""
39 options: NSLiteralSearch
40 range: NSMakeRange(0, [sanitized length])];
41 input = sanitized;
42 }
43
[617]44 NSString *temp = [[NSString alloc] initWithFormat: @"my $s = eval {UnixDate(q|%@|, '%%q')}; warn $@ if $@; $s", input];
[367]45 // NSLog(@"%@", temp);
[617]46 SV *d = eval_pv([temp UTF8String], FALSE);
[367]47 [temp release];
48 if (d == NULL) return nil;
49
50 STRLEN s_len;
51 char *s = SvPV(d, s_len);
52 if (s == NULL || s_len == 0) return nil;
53
54 NSDate *date = [dateManipFormatter dateFromString: [NSString stringWithUTF8String: s]];
55 // NSLog(@"%@", date);
56
57 return date;
58}
59
60static void init_perl(void) {
61 const char *argv[] = {"", "-CSD", "-I", "", "-MDate::Manip", "-e", "0"};
62 argv[3] = [[[NSBundle mainBundle] resourcePath] fileSystemRepresentation];
63 PERL_SYS_INIT(0, NULL);
64 my_perl = perl_alloc();
65 if (my_perl == NULL) return;
66
67 perl_construct(my_perl);
68 if (perl_parse(my_perl, xs_init, 7, (char **)argv, NULL) != 0) goto fail;
69
70 PL_exit_flags |= PERL_EXIT_DESTRUCT_END;
71 if (perl_run(my_perl) != 0) goto fail;
72
73 // XXX detect localization changes
74 eval_pv("Date_Init(\"Language=English\", \"DateFormat=non-US\", \"Internal=1\"", TRUE);
75
76 if (parse_natural_language_date(@"tomorrow") == nil) goto fail;
77
78 return;
79
80fail:
81 perl_destruct(my_perl);
82 perl_free(my_perl);
83 PERL_SYS_TERM();
84 my_perl = NULL;
85}
86
87
88// note: the documentation is misleading here, and this works.
89// <http://gcc.gnu.org/ml/gcc-patches/2004-06/msg00385.html>
90void initialize(void) __attribute__((constructor));
91
92void initialize(void) {
93 dateManipFormatter = [[NSDateFormatter alloc] init];
94 [dateManipFormatter setDateFormat: @"yyyyMMddHHmmss"]; // Date::Manip's "%q"
95 init_perl();
96}
Note: See TracBrowser for help on using the repository browser.