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

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

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

File size: 2.6 KB
Line 
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   
44    NSString *temp = [[NSString alloc] initWithFormat: @"my $s = eval {UnixDate(q|%@|, '%%q')}; warn $@ if $@; $s", input];
45    // NSLog(@"%@", temp);
46    SV *d = eval_pv([temp UTF8String], FALSE);
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.