[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 |
|
---|
| 15 | EXTERN_C void xs_init (pTHX);
|
---|
| 16 |
|
---|
| 17 | EXTERN_C void boot_DynaLoader (pTHX_ CV* cv);
|
---|
| 18 |
|
---|
| 19 | EXTERN_C void
|
---|
| 20 | xs_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 |
|
---|
| 30 | static PerlInterpreter *my_perl;
|
---|
| 31 | static NSDateFormatter *dateManipFormatter;
|
---|
| 32 |
|
---|
| 33 | NSDate *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 |
|
---|
| 60 | static 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 |
|
---|
| 80 | fail:
|
---|
| 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>
|
---|
| 90 | void initialize(void) __attribute__((constructor));
|
---|
| 91 |
|
---|
| 92 | void initialize(void) {
|
---|
| 93 | dateManipFormatter = [[NSDateFormatter alloc] init];
|
---|
| 94 | [dateManipFormatter setDateFormat: @"yyyyMMddHHmmss"]; // Date::Manip's "%q"
|
---|
| 95 | init_perl();
|
---|
| 96 | } |
---|