📄 pcre-module.c
字号:
#include <stdio.h>#include <slang.h>#include <pcre.h>SLANG_MODULE(pcre);static int PCRE_Type_Id;typedef struct{ pcre *p; pcre_extra *extra; int *ovector; unsigned int ovector_len; /* must be a multiple of 3 */ unsigned int num_matches; /* return value of pcre_exec (>= 1)*/}PCRE_Type;static void free_pcre_type (PCRE_Type *pt){ if (pt->ovector != NULL) SLfree ((char *) pt->ovector); SLfree ((char *) pt);}static SLang_MMT_Type *allocate_pcre_type (pcre *p, pcre_extra *extra){ PCRE_Type *pt; SLang_MMT_Type *mmt; int ovector_len; pt = (PCRE_Type *) SLmalloc (sizeof (PCRE_Type)); if (pt == NULL) return NULL; memset ((char *) pt, 0, sizeof (PCRE_Type)); pt->p = p; pt->extra = extra; if (0 != pcre_fullinfo (p, extra, PCRE_INFO_CAPTURECOUNT, &ovector_len)) { free_pcre_type (pt); SLang_verror (SL_INTRINSIC_ERROR, "pcre_fullinfo failed"); return NULL; } ovector_len += 1; /* allow for pattern matched */ ovector_len *= 3; /* required to be multiple of 3 */ if (NULL == (pt->ovector = (int *)SLmalloc (ovector_len * sizeof (int)))) { free_pcre_type (pt); return NULL; } pt->ovector_len = ovector_len; if (NULL == (mmt = SLang_create_mmt (PCRE_Type_Id, (VOID_STAR) pt))) { free_pcre_type (pt); return NULL; } return mmt;}static int _pcre_compile_1 (char *pattern, int options){ pcre *p; pcre_extra *extra; SLCONST char *err; int erroffset; unsigned char *table; SLang_MMT_Type *mmt; table = NULL; p = pcre_compile (pattern, options, &err, &erroffset, table); if (NULL == p) { SLang_verror (SL_INTRINSIC_ERROR, "Error compiling pattern '%s' at offset %d: %s", pattern, erroffset, err); return -1; } extra = pcre_study (p, 0, &err); /* apparantly, a NULL return is ok */ if (err != NULL) { SLang_verror (SL_INTRINSIC_ERROR, "pcre_study failed: %s", err); pcre_free (p); return -1; } if (NULL == (mmt = allocate_pcre_type (p, extra))) { pcre_free ((char *) p); pcre_free ((char *) extra); return -1; } if (-1 == SLang_push_mmt (mmt)) { SLang_free_mmt (mmt); return -1; } return 0;}static void _pcre_compile (void){ char *pattern; int options = 0; switch (SLang_Num_Function_Args) { case 2: if (-1 == SLang_pop_integer (&options)) return; /* drop */ case 1: default: if (-1 == SLang_pop_slstring (&pattern)) return; } (void) _pcre_compile_1 (pattern, options); SLang_free_slstring (pattern);}/* returns number of matches */static int _pcre_exec_1 (PCRE_Type *pt, char *str, int pos, int options){ int rc; unsigned int len; pt->num_matches = 0; len = strlen (str); if ((unsigned int) pos > len) return 0; rc = pcre_exec (pt->p, pt->extra, str, len, pos, options, pt->ovector, pt->ovector_len); if (rc == PCRE_ERROR_NOMATCH) return 0; if (rc <= 0) { SLang_verror (SL_INTRINSIC_ERROR, "pcre_exec returned %d", rc); return -1; } pt->num_matches = (unsigned int) rc; return rc;}static int _pcre_exec (void){ PCRE_Type *p; SLang_MMT_Type *mmt; char *str; int pos = 0; int options = 0; int ret = -1; switch (SLang_Num_Function_Args) { case 4: if (-1 == SLang_pop_integer (&options)) return -1; case 3: if (-1 == SLang_pop_integer (&pos)) return -1; default: if (-1 == SLang_pop_slstring (&str)) return -1; if (NULL == (mmt = SLang_pop_mmt (PCRE_Type_Id))) goto free_and_return; p = SLang_object_from_mmt (mmt); } ret = _pcre_exec_1 (p, str, pos, options); free_and_return: SLang_free_slstring (str); SLang_free_mmt (mmt); return ret;}static int get_nth_start_stop (PCRE_Type *pt, unsigned int n, unsigned int *a, unsigned int *b){ int start, stop; if (n >= pt->num_matches) return -1; start = pt->ovector[2*n]; stop = pt->ovector[2*n+1]; if ((start < 0) || (stop < start)) return -1; *a = (unsigned int) start; *b = (unsigned int) stop; return 0;}static void _pcre_nth_match (PCRE_Type *pt, int *np){ unsigned int start, stop; SLang_Array_Type *at; int two = 2; int *data; if (-1 == get_nth_start_stop (pt, (unsigned int) *np, &start, &stop)) { SLang_push_null (); return; } if (NULL == (at = SLang_create_array (SLANG_INT_TYPE, 0, NULL, &two, 1))) return; data = (int *)at->data; data[0] = (int)start; data[1] = (int)stop; (void) SLang_push_array (at, 1);}static void _pcre_nth_substr (PCRE_Type *pt, char *str, int *np){ unsigned int start, stop; unsigned int len; len = strlen (str); if ((-1 == get_nth_start_stop (pt, (unsigned int) *np, &start, &stop)) || (start > len) || (stop > len)) { SLang_push_null (); return; } str = SLang_create_nslstring (str + start, stop - start); (void) SLang_push_string (str); SLang_free_slstring (str);}/* This function converts a slang RE to a pcre expression. It performs the * following transformations: * ( --> \( * ) --> \) * # --> \# * | --> \| * { --> \{ * } --> \} * \< --> \b * \> --> \b * \C --> (?i) * \c --> (?-i) * \( --> ( * \) --> ) * \{ --> { * \} --> } * Anything else? */static char *_slang_to_pcre (char *slpattern){ char *pattern, *p, *s; unsigned int len; int in_bracket; char ch; len = strlen (slpattern); pattern = SLmalloc (3*len + 1); if (pattern == NULL) return NULL; p = pattern; s = slpattern; in_bracket = 0; while ((ch = *s++) != 0) { switch (ch) { case '{': case '}': case '(': case ')': case '#': case '|': if (0 == in_bracket) *p++ = '\\'; *p++ = ch; break; case '[': in_bracket = 1; *p++ = ch; break; case ']': in_bracket = 0; *p++ = ch; break; case '\\': ch = *s++; switch (ch) { case 0: s--;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -