summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAvi Levin <avi.levin@samsung.com>2015-09-06 07:30:37 +0300
committerAvi Levin <avi.levin@samsung.com>2015-09-06 07:30:37 +0300
commit6c702f6b34e41c422a367c82d5fe95405a2604e9 (patch)
tree34fbf8010a0ca5a20eaa66802a96a66ee92829f7
parentf8b56d827e9fe5f306cc52aa1ed780acfcb258df (diff)
Fix regex match problem with *
Now regular expression with * matches correctly.
-rw-r--r--src/lib/regex.c48
1 files changed, 33 insertions, 15 deletions
diff --git a/src/lib/regex.c b/src/lib/regex.c
index e5777a4..6edebcd 100644
--- a/src/lib/regex.c
+++ b/src/lib/regex.c
@@ -2,14 +2,16 @@
2#include <stdio.h> 2#include <stdio.h>
3#include "regex.h" 3#include "regex.h"
4 4
5enum {BRANCH, ANY, EXACT, STAR, PLUS}; 5
6enum {BRANCH, ANY, EXACT, STAR, PLUS, END};
6 7
7char* opcodes[] = { 8char* opcodes[] = {
8 "BRANCH", /* Alternative operator, "|" */ 9 "BRANCH", /* Alternative operator, "|" */
9 "ANY", /* Match any character, "." */ 10 "ANY", /* Match any character, "." */
10 "EXACT", /* Match exact string */ 11 "EXACT", /* Match exact string */
11 "STAR", /* Match zero or more times "*" */ 12 "STAR", /* Match zero or more times "*" */
12 "PLUS" /* Match one or more times, "+" */ 13 "PLUS", /* Match one or more times, "+" */
14 "END" /* Match end of string */
13}; 15};
14 16
15//copy just last letter from last code 17//copy just last letter from last code
@@ -36,7 +38,7 @@ void fix_prev(struct regex_compiled *sre)
36void regex_dump(struct regex_compiled *sre) 38void regex_dump(struct regex_compiled *sre)
37{ 39{
38 int i = 0; 40 int i = 0;
39 41 printf("data %s\n", sre->data);
40 for(; i < sre->code_size; i++) 42 for(; i < sre->code_size; i++)
41 printf("%s %d %d\n", opcodes[sre->code[i][0]], sre->code[i][1], sre->code[i][2]); 43 printf("%s %d %d\n", opcodes[sre->code[i][0]], sre->code[i][1], sre->code[i][2]);
42} 44}
@@ -44,6 +46,7 @@ void regex_dump(struct regex_compiled *sre)
44int regex_compile(struct regex_compiled *sre, const char *re) 46int regex_compile(struct regex_compiled *sre, const char *re)
45{ 47{
46 sre->code_size = sre->data_size = 0; 48 sre->code_size = sre->data_size = 0;
49 int last = 0;
47 50
48 while(*re){ 51 while(*re){
49 sre->code[sre->code_size][1] = 0; 52 sre->code[sre->code_size][1] = 0;
@@ -52,19 +55,19 @@ int regex_compile(struct regex_compiled *sre, const char *re)
52 55
53 case '*': 56 case '*':
54 case '+': 57 case '+':
55 sre->code[sre->code_size++][0] = *re == '*' ? STAR : PLUS; 58 last = sre->code[sre->code_size++][0] = *re == '*' ? STAR : PLUS;
56 if(sre->code_size > 1 ) 59 if(sre->code_size > 1 )
57 fix_prev(sre); 60 fix_prev(sre);
58 else return -1; 61 else return -1;
59 break; 62 break;
60 case '.': 63 case '.':
61 sre->code[sre->code_size++][0] = ANY; 64 last = sre->code[sre->code_size++][0] = ANY;
62 break; 65 break;
63 default: 66 default:
64 sre->data[sre->data_size++] = *re; 67 sre->data[sre->data_size++] = *re;
65 if(sre->data_size == 0 || sre->code[sre->code_size-1][0] != EXACT) 68 if(sre->data_size == 0 || last != EXACT)
66 { 69 {
67 sre->code[sre->code_size++][0] = EXACT; 70 last = sre->code[sre->code_size++][0] = EXACT;
68 sre->code[sre->code_size-1][1] = sre->data_size - 1; 71 sre->code[sre->code_size-1][1] = sre->data_size - 1;
69 } 72 }
70 sre->code[sre->code_size-1][2] = sre->data_size - sre->code[sre->code_size-1][1]; 73 sre->code[sre->code_size-1][2] = sre->data_size - sre->code[sre->code_size-1][1];
@@ -72,7 +75,10 @@ int regex_compile(struct regex_compiled *sre, const char *re)
72 re++; 75 re++;
73 } 76 }
74 sre->data[sre->data_size] = 0; 77 sre->data[sre->data_size] = 0;
75 78 sre->code[sre->code_size][0] = END;
79 sre->code[sre->code_size][1] = 0;
80 sre->code[sre->code_size][2] = 1;
81 sre->code_size++;
76 return 1; 82 return 1;
77} 83}
78 84
@@ -80,26 +86,38 @@ int regex_match(struct regex_compiled *sre, const char *str, int code_pos)
80{ 86{
81 int res = 1; 87 int res = 1;
82 88
83 while(res && (code_pos < sre->code_size) && *str) 89 while(res && (code_pos < sre->code_size))
84 { 90 {
85 switch(sre->code[code_pos][0]){ 91 switch(sre->code[code_pos][0]){
86 92
87 case STAR: 93 case STAR:
88 case PLUS: 94 case PLUS:
89 if(sre->code[code_pos][0] == PLUS || !regex_match(sre, str, code_pos+2)) 95 res = 0;
90 while(*str && !(res = regex_match(sre, str, code_pos+1))){str++;} 96 if((sre->code[code_pos][0] == STAR) && regex_match(sre, str, code_pos+2))
91 return res; 97 return 1;
98 else {
99 char c = sre->data[sre->code[code_pos+1][1]];
100 while( *(str) && !(res = regex_match(sre, str+1, code_pos+2))
101 && ( (sre->code[code_pos+1][0] == ANY || *(str) == c)))
102 {str++;}
103
104 return res && *str && (sre->code[code_pos+1][0] == ANY || *(str) == c);
105 }
106 break;
92 case ANY: 107 case ANY:
93 str++; 108 str++;
94 break; 109 break;
110 case END:
111 res = !*str;
112 break;
95 default: 113 default:
96 if (strncmp(sre->data+sre->code[code_pos][1], str, sre->code[code_pos][2])) 114 if (strncmp(sre->data+sre->code[code_pos][1], str, sre->code[code_pos][2])!=0)
97 res = 0; 115 res = 0;
98 str += sre->code[code_pos][2]; 116 else str += sre->code[code_pos][2];
99 } 117 }
100 code_pos++; 118 code_pos++;
101 } 119 }
102 120
103 return (code_pos >= sre->code_size || ( code_pos = sre->code_size - 2 && sre->code[code_pos][0] == STAR)) 121 return (code_pos >= sre->code_size || ( code_pos = sre->code_size - 2 && sre->code[code_pos][0] == STAR))
104 && res && !*str; 122 && res;
105} 123}