]> rtime.felk.cvut.cz Git - hornmich/skoda-qr-demo.git/blob - QRScanner/mobile/jni/thirdparty/mujs/jsregexp.c
Add MuPDF native source codes
[hornmich/skoda-qr-demo.git] / QRScanner / mobile / jni / thirdparty / mujs / jsregexp.c
1 #include "jsi.h"
2 #include "jsvalue.h"
3 #include "jsbuiltin.h"
4 #include "regex.h"
5
6 void js_newregexp(js_State *J, const char *pattern, int flags)
7 {
8         const char *error;
9         js_Object *obj;
10         Reprog *prog;
11         int opts;
12
13         obj = jsV_newobject(J, JS_CREGEXP, J->RegExp_prototype);
14
15         opts = 0;
16         if (flags & JS_REGEXP_I) opts |= REG_ICASE;
17         if (flags & JS_REGEXP_M) opts |= REG_NEWLINE;
18
19         prog = js_regcomp(pattern, opts, &error);
20         if (!prog)
21                 js_syntaxerror(J, "regular expression: %s", error);
22
23         obj->u.r.prog = prog;
24         obj->u.r.source = pattern;
25         obj->u.r.flags = flags;
26         obj->u.r.last = 0;
27         js_pushobject(J, obj);
28 }
29
30 void js_RegExp_prototype_exec(js_State *J, js_Regexp *re, const char *text)
31 {
32         unsigned int i;
33         int opts;
34         Resub m;
35
36         opts = 0;
37         if (re->flags & JS_REGEXP_G) {
38                 if (re->last > strlen(text)) {
39                         re->last = 0;
40                         js_pushnull(J);
41                         return;
42                 }
43                 if (re->last > 0) {
44                         text += re->last;
45                         opts |= REG_NOTBOL;
46                 }
47         }
48
49         if (!js_regexec(re->prog, text, &m, opts)) {
50                 js_newarray(J);
51                 js_pushstring(J, text);
52                 js_setproperty(J, -2, "input");
53                 js_pushnumber(J, js_utfptrtoidx(text, m.sub[0].sp));
54                 js_setproperty(J, -2, "index");
55                 for (i = 0; i < m.nsub; ++i) {
56                         js_pushlstring(J, m.sub[i].sp, m.sub[i].ep - m.sub[i].sp);
57                         js_setindex(J, -2, i);
58                 }
59                 if (re->flags & JS_REGEXP_G)
60                         re->last = re->last + (m.sub[0].ep - text);
61                 return;
62         }
63
64         if (re->flags & JS_REGEXP_G)
65                 re->last = 0;
66
67         js_pushnull(J);
68 }
69
70 static void Rp_test(js_State *J)
71 {
72         js_Regexp *re;
73         const char *text;
74         int opts;
75         Resub m;
76
77         re = js_toregexp(J, 0);
78         text = js_tostring(J, 1);
79
80         opts = 0;
81         if (re->flags & JS_REGEXP_G) {
82                 if (re->last > strlen(text)) {
83                         re->last = 0;
84                         js_pushboolean(J, 0);
85                         return;
86                 }
87                 if (re->last > 0) {
88                         text += re->last;
89                         opts |= REG_NOTBOL;
90                 }
91         }
92
93         if (!js_regexec(re->prog, text, &m, opts)) {
94                 if (re->flags & JS_REGEXP_G)
95                         re->last = re->last + (m.sub[0].ep - text);
96                 js_pushboolean(J, 1);
97                 return;
98         }
99
100         if (re->flags & JS_REGEXP_G)
101                 re->last = 0;
102
103         js_pushboolean(J, 0);
104 }
105
106 static void jsB_new_RegExp(js_State *J)
107 {
108         js_Regexp *old;
109         const char *pattern;
110         int flags;
111
112         if (js_isregexp(J, 1)) {
113                 if (js_isdefined(J, 2))
114                         js_typeerror(J, "cannot supply flags when creating one RegExp from another");
115                 old = js_toregexp(J, 1);
116                 pattern = old->source;
117                 flags = old->flags;
118         } else if (js_isundefined(J, 1)) {
119                 pattern = "";
120                 flags = 0;
121         } else {
122                 pattern = js_tostring(J, 1);
123                 flags = 0;
124         }
125
126         if (js_isdefined(J, 2)) {
127                 const char *s = js_tostring(J, 2);
128                 int g = 0, i = 0, m = 0;
129                 while (*s) {
130                         if (*s == 'g') ++g;
131                         else if (*s == 'i') ++i;
132                         else if (*s == 'm') ++m;
133                         else js_syntaxerror(J, "invalid regular expression flag: '%c'", *s);
134                         ++s;
135                 }
136                 if (g > 1) js_syntaxerror(J, "invalid regular expression flag: 'g'");
137                 if (i > 1) js_syntaxerror(J, "invalid regular expression flag: 'i'");
138                 if (m > 1) js_syntaxerror(J, "invalid regular expression flag: 'm'");
139                 if (g) flags |= JS_REGEXP_G;
140                 if (i) flags |= JS_REGEXP_I;
141                 if (m) flags |= JS_REGEXP_M;
142         }
143
144         js_newregexp(J, pattern, flags);
145 }
146
147 static void jsB_RegExp(js_State *J)
148 {
149         if (js_gettop(J) == 2 && js_isregexp(J, 1))
150                 return;
151         jsB_new_RegExp(J);
152 }
153
154 static void Rp_toString(js_State *J)
155 {
156         js_Regexp *re;
157         char *out;
158
159         re = js_toregexp(J, 0);
160
161         out = js_malloc(J, strlen(re->source) + 6); /* extra space for //gim */
162         strcpy(out, "/");
163         strcat(out, re->source);
164         strcat(out, "/");
165         if (re->flags & JS_REGEXP_G) strcat(out, "g");
166         if (re->flags & JS_REGEXP_I) strcat(out, "i");
167         if (re->flags & JS_REGEXP_M) strcat(out, "m");
168
169         if (js_try(J)) {
170                 js_free(J, out);
171                 js_throw(J);
172         }
173         js_pop(J, 0);
174         js_pushstring(J, out);
175         js_endtry(J);
176         js_free(J, out);
177 }
178
179 static void Rp_exec(js_State *J)
180 {
181         js_RegExp_prototype_exec(J, js_toregexp(J, 0), js_tostring(J, 1));
182 }
183
184 void jsB_initregexp(js_State *J)
185 {
186         js_pushobject(J, J->RegExp_prototype);
187         {
188                 jsB_propf(J, "toString", Rp_toString, 0);
189                 jsB_propf(J, "test", Rp_test, 0);
190                 jsB_propf(J, "exec", Rp_exec, 0);
191         }
192         js_newcconstructor(J, jsB_RegExp, jsB_new_RegExp, "RegExp", 1);
193         js_defglobal(J, "RegExp", JS_DONTENUM);
194 }