Browse Source

feat: Regex错误不使用全局变量传递

SongZihuan 3 năm trước cách đây
mục cha
commit
c34b9bd998
4 tập tin đã thay đổi với 43 bổ sung25 xóa
  1. 2 3
      include/tool/regex.h
  2. 2 2
      src/core/env.c
  3. 33 14
      src/tool/regex.c
  4. 6 6
      test/src/tool_regex.c

+ 2 - 3
include/tool/regex.h

@@ -6,10 +6,9 @@
 #include "aFunToolExport.h"
 
 typedef struct af_Regex af_Regex;
-extern char regex_error[REGEX_ERROR_SIZE];
 
-AFUN_TOOL_EXPORT af_Regex *makeRegex(char *pattern);
+AFUN_TOOL_EXPORT af_Regex *makeRegex(char *pattern, char **error);
 AFUN_TOOL_EXPORT void freeRegex(af_Regex *rg);
-AFUN_TOOL_EXPORT int matchRegex(char *subject, af_Regex *rg);
+AFUN_TOOL_EXPORT int matchRegex(char *subject, af_Regex *rg, char **error);
 
 #endif //AFUN_REGEX

+ 2 - 2
src/core/env.c

@@ -1304,7 +1304,7 @@ void popActivity(bool is_normal, af_Message *msg, af_Environment *env) {
 }
 
 static af_LiteralRegex *makeLiteralRegex(char *pattern, char *func, bool in_protect) {
-    af_Regex *rg = makeRegex(pattern);
+    af_Regex *rg = makeRegex(pattern, NULL);
     if (rg == NULL)
         return NULL;
 
@@ -1344,7 +1344,7 @@ bool pushLiteralRegex(char *pattern, char *func, bool in_protect, af_Environment
  */
 bool checkLiteralCode(char *literal, char **func, bool *in_protect, af_Environment *env) {
     for (af_LiteralRegex *lr = env->core->lr; lr != NULL; lr = lr->next) {
-        if (matchRegex(literal, lr->rg) == 1) {
+        if (matchRegex(literal, lr->rg, NULL) == 1) {
             if (func != NULL)
                 *func = lr->func;  // 不使用复制
             if (in_protect != NULL)

+ 33 - 14
src/tool/regex.c

@@ -5,20 +5,27 @@
 #include "pcre2.h"
 #include "__regex.h"
 
-char regex_error[REGEX_ERROR_SIZE];
-
-af_Regex *makeRegex(char *pattern) {
-    if (!isCharUTF8(pattern))
+af_Regex *makeRegex(char *pattern, char **error) {
+    if (error)
+        *error = NULL;
+    if (!isCharUTF8(pattern)) {
+        *error = strCopy("Pattern not utf-8");
         return NULL;
+    }
 
     int error_code;
     size_t erroroffset;
+    char regex_error[REGEX_ERROR_SIZE];
     pcre2_code *re = pcre2_compile((PCRE2_SPTR)pattern, PCRE2_ZERO_TERMINATED, 0, &error_code, &erroroffset, NULL);
 
     if (re == NULL) {
-        PCRE2_UCHAR buffer[256];
-        pcre2_get_error_message(error_code, buffer, sizeof(buffer));
-        snprintf(regex_error, sizeof(regex_error), "Regex compilation failed at offset %d: %s\n", (int)erroroffset, buffer);
+        if (error) {
+            PCRE2_UCHAR buffer[256];
+            pcre2_get_error_message(error_code, buffer, sizeof(buffer));
+
+            snprintf(regex_error, sizeof(regex_error), "Regex failed: %d: %s\n", (int) erroroffset, buffer);
+            *error = strCopy(regex_error);
+        }
         return NULL;
     }
 
@@ -41,10 +48,16 @@ void freeRegex(af_Regex *rg) {
  * 返回  (0) - 不可完全匹配或不可匹配
  * 返回 (>0) - 失败
  */
-int matchRegex(char *subject, af_Regex *rg) {
-    if (!isCharUTF8(subject))
+int matchRegex(char *subject, af_Regex *rg, char **error) {
+    if (error != NULL)
+        *error = NULL;
+    if (!isCharUTF8(subject)) {
+        if (error != NULL)
+            *error = strCopy("Subject not utf-8");
         return 0;
+    }
 
+    char regex_error[REGEX_ERROR_SIZE];
     PCRE2_SPTR sub = (PCRE2_SPTR)subject;
     PCRE2_SIZE sub_len = strlen(subject);
     pcre2_match_data *match_data = pcre2_match_data_create_from_pattern(rg->re, NULL);
@@ -55,17 +68,23 @@ int matchRegex(char *subject, af_Regex *rg) {
         if (rc == PCRE2_ERROR_NOMATCH)
             return 0;
         else {
-            snprintf(regex_error, sizeof(regex_error), "Regex match '%s' failed by '%s'\n", subject, rg->pattern);
+            if (error != NULL) {
+                snprintf(regex_error, sizeof(regex_error), "Regex match '%s' failed by '%s'\n", subject, rg->pattern);
+                *error = strCopy(regex_error);
+            }
             return -1;
         }
     }
 
     PCRE2_SIZE *ovector = pcre2_get_ovector_pointer(match_data);
     if (ovector[0] > ovector[1]) {
-        snprintf(regex_error, sizeof(regex_error),
-                 "\\K was used in an assertion to set the match start after its end.\n"
-                 "From end to start the match was: %.*s\n",
-                 (int)(ovector[0] - ovector[1]), (char *)(subject + ovector[1]));
+        if (error != NULL) {
+            snprintf(regex_error, sizeof(regex_error),
+                     "\\K was used in an assertion to set the match start after its end.\n"
+                     "From end to start the match was: %.*s\n",
+                     (int) (ovector[0] - ovector[1]), (char *) (subject + ovector[1]));
+            *error = strCopy(regex_error);
+        }
         pcre2_match_data_free(match_data);
         return -2;
     }

+ 6 - 6
test/src/tool_regex.c

@@ -3,9 +3,9 @@
 #include "regex.h"
 
 int main() {
-    af_Regex *rg = makeRegex("Hello嘿.*d");
-    int rc1 = matchRegex("Hello嘿World", rg);
-    int rc2 = matchRegex("Nossss", rg);
+    af_Regex *rg = makeRegex("Hello嘿.*d", NULL);
+    int rc1 = matchRegex("Hello嘿World", rg, NULL);
+    int rc2 = matchRegex("Nossss", rg, NULL);
     freeRegex(rg);
     if (rc1 != 1 || rc2 != 0) {
         printf("Failed rg1: %d/1, %d/0\n", rc1, rc2);
@@ -13,9 +13,9 @@ int main() {
     } else
         printf("rg1 success\n");
 
-    af_Regex *rg2 = makeRegex("你|好");
-    int rc3 = matchRegex("你", rg2);
-    int rc4 = matchRegex("Nosssss", rg2);
+    af_Regex *rg2 = makeRegex("你|好", NULL);
+    int rc3 = matchRegex("你", rg2, NULL);
+    int rc4 = matchRegex("Nosssss", rg2, NULL);
     freeRegex(rg2);
     if (rc3 != 1 || rc4 != 0) {
         printf("Failed rg2: %d/1, %d/0\n", rc1, rc2);