HistoryView: don't load in commit information in a separate thread anymore
[GitX.git] / NSString_RegEx.m
blob38d384887e864e8ff9973c7ee378cecaa1ebed4e
1 //
2 //  NSString_RegEx.m
3 //
4 //  Created by John R Chang on 2005-11-08.
5 //  This code is Creative Commons Public Domain.  You may use it for any purpose whatsoever.
6 //  http://creativecommons.org/licenses/publicdomain/
7 //
9 #import "NSString_RegEx.h"
10 #include <regex.h>
13 @implementation NSString (RegEx)
15 - (NSArray *) substringsMatchingRegularExpression:(NSString *)pattern count:(int)nmatch options:(int)options ranges:(NSArray **)ranges error:(NSError **)error
17         options |= REG_EXTENDED;
18         if (error)
19                 *error = nil;
21         int errcode = 0;
22         regex_t preg;
23         regmatch_t * pmatch = NULL;
24         NSMutableArray * outMatches = nil;
25         
26         // Compile the regular expression
27         errcode = regcomp(&preg, [pattern UTF8String], options);
28         if (errcode != 0)
29                 goto catch_error;       // regcomp error
30         
31         // Match the regular expression against substring self
32         pmatch = calloc(sizeof(regmatch_t), nmatch+1);
33         errcode = regexec(&preg, [self UTF8String], (nmatch<0 ? 0 : nmatch+1), pmatch, 0);
35         /*if (errcode == REG_NOMATCH)
36         {
37                 outMatches = [NSMutableArray array];
38                 goto catch_exit;        // no match
39         }*/     
40         if (errcode != 0)
41                 goto catch_error;       // regexec error
43         if (nmatch == -1)
44         {
45                 outMatches = [NSArray arrayWithObject:self];
46                 goto catch_exit;        // simple match
47         }
49         // Iterate through pmatch
50         outMatches = [NSMutableArray array];
51         if (ranges)
52                 *ranges = [NSMutableArray array];
53         int i;
54         for (i=0; i<nmatch+1; i++)
55         {
56                 if (pmatch[i].rm_so == -1 || pmatch[i].rm_eo == -1)
57                         break;
59                 NSRange range = NSMakeRange(pmatch[i].rm_so, pmatch[i].rm_eo - pmatch[i].rm_so);
60                 NSString * substring = [[[NSString alloc] initWithBytes:[self UTF8String] + range.location
61                                                                                                                  length:range.length
62                                                                                                            encoding:NSUTF8StringEncoding] autorelease];
63                 [outMatches addObject:substring];
65                 if (ranges)
66                 {
67                         NSValue * value = [NSValue valueWithRange:range];
68                         [(NSMutableArray *)*ranges addObject:value];
69                 }
70         }
72 catch_error:
73         if (errcode != 0 && error)
74         {
75                 // Construct error object
76                 NSMutableDictionary * userInfo = [NSMutableDictionary dictionary];
77                 char errbuf[256];
78                 int len = regerror(errcode, &preg, errbuf, sizeof(errbuf));
79                 if (len > 0)
80                         [userInfo setObject:[NSString stringWithUTF8String:errbuf] forKey:NSLocalizedDescriptionKey];
81                 *error = [NSError errorWithDomain:@"regerror" code:errcode userInfo:userInfo];
82         }
84 catch_exit:
85         if (pmatch)
86                 free(pmatch);
87         regfree(&preg);
88         return outMatches;
91 - (BOOL) grep:(NSString *)pattern options:(int)options
93         NSArray * substrings = [self substringsMatchingRegularExpression:pattern count:-1 options:options ranges:NULL error:NULL];
94         return (substrings && [substrings count] > 0);
97 @end