Permalink
Browse files

Removed pcre and used my own text scanner.

This increased performance.
  • Loading branch information...
1 parent 40b2d5a commit cd6681aa99300524e0aa5efc02dac46b1f680f8d @pope pope committed Oct 14, 2009
Showing with 40 additions and 43 deletions.
  1. +36 −43 ext/version_sorter/version_sorter.c
  2. +4 −0 ext/version_sorter/version_sorter.h
@@ -11,33 +11,18 @@
#include <stdio.h>
#include <string.h>
#include <ctype.h>
-#include <pcre.h>
#include "version_sorter.h"
-static pcre *expr;
static VersionSortingItem * version_sorting_item_init(const char *);
static void version_sorting_item_free(VersionSortingItem *);
static void version_sorting_item_add_piece(VersionSortingItem *, char *);
-static void setup_version_regex(void);
static void parse_version_word(VersionSortingItem *);
static void create_normalized_version(VersionSortingItem *, const int);
static int compare_by_version(const void *, const void *);
+static enum scan_state scan_state_get(const char);
-void
-setup_version_regex(void)
-{
- const char *pattern = "(\\d+|[a-zA-Z]+)";
- const char *errstr;
- int erroffset;
-
- if (!(expr = pcre_compile(pattern, 0, &errstr, &erroffset, 0))) {
- fprintf(stderr, "ERROR: %s: %s\n", pattern, errstr);
- exit(EXIT_FAILURE);
- }
-}
-
VersionSortingItem *
version_sorting_item_init(const char *original)
{
@@ -96,48 +81,56 @@ version_sorting_item_add_piece(VersionSortingItem *vsi, char *str)
}
}
-void
-parse_version_word(VersionSortingItem *vsi)
+enum scan_state
+scan_state_get(const char c)
{
- if (expr == NULL) {
- setup_version_regex();
- }
-
- int ovecsize = 0;
- if (pcre_fullinfo(expr, NULL, PCRE_INFO_CAPTURECOUNT, &ovecsize) != 0) {
- DIE("ERROR: Problem calling pcre_fullinfo")
- }
- ovecsize = (ovecsize + 1) * 3;
-
- int *ovector = calloc(ovecsize, sizeof(int));
- if (ovector == NULL) {
- DIE("ERROR: Not enough memory to allocate ovector")
+ if (isdigit(c)) {
+ return digit;
+ } else if (isalpha(c)) {
+ return alpha;
+ } else {
+ return other;
}
- int offset = 0;
- int flags = 0;
- char *part;
- int size;
+}
- while (0 < pcre_exec(expr, 0, vsi->original, vsi->original_len, offset, flags, ovector, ovecsize)) {
+void
+parse_version_word(VersionSortingItem *vsi)
+{
+ int start = 0, end = 0, size = 0;
+ char current_char, next_char;
+ char *part;
+ enum scan_state current_state, next_state;
+
+ while ((current_char = vsi->original[start]) != '\0') {
+ current_state = scan_state_get(current_char);
- size = ovector[1] - ovector[0];
+ if (current_state == other) {
+ start++;
+ end = start;
+ continue;
+ }
+
+ do {
+ end++;
+ next_char = vsi->original[end];
+ next_state = scan_state_get(next_char);
+ } while (next_char != '\0' && current_state == next_state);
+ size = end - start;
+
part = malloc((size+1) * sizeof(char));
if (part == NULL) {
DIE("ERROR: Not enough memory to allocate word")
}
-
- memcpy(part, vsi->original+ovector[0], size);
+
+ memcpy(part, vsi->original+start, size);
part[size] = '\0';
version_sorting_item_add_piece(vsi, part);
- offset = ovector[1];
- flags |= PCRE_NOTBOL;
+ start = end;
}
-
- free(ovector);
}
void
@@ -38,6 +38,10 @@ typedef struct _VersionPiece {
struct _VersionPiece *next;
} VersionPiece;
+enum scan_state {
+ digit, alpha, other
+};
+
extern void version_sorter_sort(char **, size_t);
#endif /* _VERSION_SORTER_H */

0 comments on commit cd6681a

Please sign in to comment.