Skip to content

Instantly share code, notes, and snippets.

@alphaKAI
Last active March 27, 2016 10:13
Show Gist options
  • Save alphaKAI/82adc162b9c68e5dc7d7 to your computer and use it in GitHub Desktop.
Save alphaKAI/82adc162b9c68e5dc7d7 to your computer and use it in GitHub Desktop.
An Example of D bindings for PCRE
#include <pcre.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdbool.h>
#define DEBUG false
struct Matchs {
int length;
const char** matchs;
};
pcre* compileRegex(const char* pattern,
pcre_extra* pcreExtra) {
pcre* regexCompiled;
int pcreErrorOffset;
const char* pcreErrorStr;
regexCompiled = pcre_compile(
pattern,
0,
&pcreErrorStr,
&pcreErrorOffset,
NULL);
if (regexCompiled == NULL) {
if (DEBUG)
printf("ERROR - Could not compile\n");
return NULL;
}
pcreExtra = pcre_study(regexCompiled, 0, &pcreErrorStr);
if (pcreErrorStr != NULL) {
if (DEBUG)
printf("ERROR - Could not study\n");
return NULL;
}
return regexCompiled;
}
struct Matchs* match(
const char* target,
pcre* regexCompiled,
pcre_extra* pcreExtra
) {
struct Matchs* m;
int l;
int subStrVecLen;
int* subStrVec;
const char* psubStrMatchStr;
m = NULL;
subStrVecLen = strlen(target) + 1;
subStrVec = (int*)malloc(sizeof(int) * subStrVecLen);
int pcreExecRet = pcre_exec(regexCompiled,
pcreExtra,
target,
strlen(target),
0,
0,
subStrVec,
subStrVecLen);
if (pcreExecRet < 0) {
switch (pcreExecRet) {
case PCRE_ERROR_NOMATCH :
if (DEBUG)
printf("String did not match the pattern\n");
break;
case PCRE_ERROR_NULL :
if (DEBUG)
printf("Something was null\n");
break;
case PCRE_ERROR_BADOPTION :
if (DEBUG)
printf("A bad option was passed\n");
break;
case PCRE_ERROR_BADMAGIC :
if (DEBUG)
printf("Magic number bad (compiled re corrupt?)\n");
break;
case PCRE_ERROR_UNKNOWN_NODE :
if (DEBUG)
printf("Something kooky in the compiled re\n");
break;
case PCRE_ERROR_NOMEMORY :
if (DEBUG)
printf("Ran out of memory\n");
break;
default :
if (DEBUG)
printf("Unknown error\n");
break;
}
} else {
m = (struct Matchs*)malloc(sizeof(struct Matchs));
m->length = pcreExecRet;
m->matchs = (const char**)malloc(sizeof(char*) * pcreExecRet);
for (int j = 0; j < pcreExecRet; j++) {
pcre_get_substring(target, subStrVec, pcreExecRet, j, &(psubStrMatchStr));
m->matchs[j] = (char*)malloc(sizeof(char) * strlen(psubStrMatchStr) + 1);
m->matchs[j] = psubStrMatchStr;
}
}
free(subStrVec);
return m;
}
void freeMatchs(struct Matchs* m) {
if (m != NULL) {
free(m->matchs);
free(m);
}
}
extern (C) {
struct Matchs {
int length;
char** matchs;
}
struct pcre;
struct pcre_extra;
pcre* compileRegex(const char*, pcre_extra*);
Matchs* match(const char*, pcre*, pcre_extra*);
void freeMatchs(Matchs* m);
}
/*
Rquirements:
- PCRE 8.38
- DMD Latest
Build:
$ gcc -c pcre4dc.c
$ dmd -c pcre4dd.d
$ dmd test.d pcre4dc.o pcre4dd.o -L-lpcre
*/
import std.string,
std.stdio;
import pcre4dd;
void main() {
pcre_extra* pcreExtra;
pcre* regexCompiled;
string pattern = "(.+)\\[(.+)\\]\\{(.+)\\}";
string[] tests = [
"alpha[KAI]{NET}",
"Apple[Orange]{banana}",
"abcdef"
];
regexCompiled = compileRegex(pattern.toStringz, pcreExtra);
if (regexCompiled is null) {
throw new Error("Failed to compile");
}
foreach (test; tests) {
writeln("TEST : ", test);
Matchs* m = match(test.toStringz,
regexCompiled,
pcreExtra);
if (m is null) {
writeln(" -> Didn't match the pattern.");
} else {
for (int i; i < m.length; i++) {
writeln(" -> ", m.matchs[i].fromStringz);
}
}
freeMatchs(m);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment