Mercurial > hgrepos > Python2 > PyMuPDF
comparison mupdf-source/thirdparty/mujs/jsbuiltin.c @ 2:b50eed0cc0ef upstream
ADD: MuPDF v1.26.7: the MuPDF source as downloaded by a default build of PyMuPDF 1.26.4.
The directory name has changed: no version number in the expanded directory now.
| author | Franz Glasner <fzglas.hg@dom66.de> |
|---|---|
| date | Mon, 15 Sep 2025 11:43:07 +0200 |
| parents | |
| children |
comparison
equal
deleted
inserted
replaced
| 1:1d09e1dec1d9 | 2:b50eed0cc0ef |
|---|---|
| 1 #include "jsi.h" | |
| 2 #include "regexp.h" | |
| 3 | |
| 4 static void jsB_globalf(js_State *J, const char *name, js_CFunction cfun, int n) | |
| 5 { | |
| 6 js_newcfunction(J, cfun, name, n); | |
| 7 js_defglobal(J, name, JS_DONTENUM); | |
| 8 } | |
| 9 | |
| 10 void jsB_propf(js_State *J, const char *name, js_CFunction cfun, int n) | |
| 11 { | |
| 12 const char *pname = strrchr(name, '.'); | |
| 13 pname = pname ? pname + 1 : name; | |
| 14 js_newcfunction(J, cfun, name, n); | |
| 15 js_defproperty(J, -2, pname, JS_DONTENUM); | |
| 16 } | |
| 17 | |
| 18 void jsB_propn(js_State *J, const char *name, double number) | |
| 19 { | |
| 20 js_pushnumber(J, number); | |
| 21 js_defproperty(J, -2, name, JS_READONLY | JS_DONTENUM | JS_DONTCONF); | |
| 22 } | |
| 23 | |
| 24 void jsB_props(js_State *J, const char *name, const char *string) | |
| 25 { | |
| 26 js_pushliteral(J, string); | |
| 27 js_defproperty(J, -2, name, JS_DONTENUM); | |
| 28 } | |
| 29 | |
| 30 static void jsB_parseInt(js_State *J) | |
| 31 { | |
| 32 const char *s = js_tostring(J, 1); | |
| 33 int radix = js_isdefined(J, 2) ? js_tointeger(J, 2) : 0; | |
| 34 double sign = 1; | |
| 35 double n; | |
| 36 char *e; | |
| 37 | |
| 38 while (jsY_iswhite(*s) || jsY_isnewline(*s)) | |
| 39 ++s; | |
| 40 if (*s == '-') { | |
| 41 ++s; | |
| 42 sign = -1; | |
| 43 } else if (*s == '+') { | |
| 44 ++s; | |
| 45 } | |
| 46 if (radix == 0) { | |
| 47 radix = 10; | |
| 48 if (s[0] == '0' && (s[1] == 'x' || s[1] == 'X')) { | |
| 49 s += 2; | |
| 50 radix = 16; | |
| 51 } | |
| 52 } else if (radix < 2 || radix > 36) { | |
| 53 js_pushnumber(J, NAN); | |
| 54 return; | |
| 55 } | |
| 56 n = js_strtol(s, &e, radix); | |
| 57 if (s == e) | |
| 58 js_pushnumber(J, NAN); | |
| 59 else | |
| 60 js_pushnumber(J, n * sign); | |
| 61 } | |
| 62 | |
| 63 static void jsB_parseFloat(js_State *J) | |
| 64 { | |
| 65 const char *s = js_tostring(J, 1); | |
| 66 char *e; | |
| 67 double n; | |
| 68 | |
| 69 while (jsY_iswhite(*s) || jsY_isnewline(*s)) ++s; | |
| 70 if (!strncmp(s, "Infinity", 8)) | |
| 71 js_pushnumber(J, INFINITY); | |
| 72 else if (!strncmp(s, "+Infinity", 9)) | |
| 73 js_pushnumber(J, INFINITY); | |
| 74 else if (!strncmp(s, "-Infinity", 9)) | |
| 75 js_pushnumber(J, -INFINITY); | |
| 76 else { | |
| 77 n = js_stringtofloat(s, &e); | |
| 78 if (e == s) | |
| 79 js_pushnumber(J, NAN); | |
| 80 else | |
| 81 js_pushnumber(J, n); | |
| 82 } | |
| 83 } | |
| 84 | |
| 85 static void jsB_isNaN(js_State *J) | |
| 86 { | |
| 87 double n = js_tonumber(J, 1); | |
| 88 js_pushboolean(J, isnan(n)); | |
| 89 } | |
| 90 | |
| 91 static void jsB_isFinite(js_State *J) | |
| 92 { | |
| 93 double n = js_tonumber(J, 1); | |
| 94 js_pushboolean(J, isfinite(n)); | |
| 95 } | |
| 96 | |
| 97 static void Encode(js_State *J, const char *str_, const char *unescaped) | |
| 98 { | |
| 99 /* NOTE: volatile to silence GCC warning about longjmp clobbering a variable */ | |
| 100 const char * volatile str = str_; | |
| 101 js_Buffer *sb = NULL; | |
| 102 | |
| 103 static const char *HEX = "0123456789ABCDEF"; | |
| 104 | |
| 105 if (js_try(J)) { | |
| 106 js_free(J, sb); | |
| 107 js_throw(J); | |
| 108 } | |
| 109 | |
| 110 while (*str) { | |
| 111 int c = (unsigned char) *str++; | |
| 112 if (strchr(unescaped, c)) | |
| 113 js_putc(J, &sb, c); | |
| 114 else { | |
| 115 js_putc(J, &sb, '%'); | |
| 116 js_putc(J, &sb, HEX[(c >> 4) & 0xf]); | |
| 117 js_putc(J, &sb, HEX[c & 0xf]); | |
| 118 } | |
| 119 } | |
| 120 js_putc(J, &sb, 0); | |
| 121 | |
| 122 js_pushstring(J, sb ? sb->s : ""); | |
| 123 js_endtry(J); | |
| 124 js_free(J, sb); | |
| 125 } | |
| 126 | |
| 127 static void Decode(js_State *J, const char *str_, const char *reserved) | |
| 128 { | |
| 129 /* NOTE: volatile to silence GCC warning about longjmp clobbering a variable */ | |
| 130 const char * volatile str = str_; | |
| 131 js_Buffer *sb = NULL; | |
| 132 int a, b; | |
| 133 | |
| 134 if (js_try(J)) { | |
| 135 js_free(J, sb); | |
| 136 js_throw(J); | |
| 137 } | |
| 138 | |
| 139 while (*str) { | |
| 140 int c = (unsigned char) *str++; | |
| 141 if (c != '%') | |
| 142 js_putc(J, &sb, c); | |
| 143 else { | |
| 144 if (!str[0] || !str[1]) | |
| 145 js_urierror(J, "truncated escape sequence"); | |
| 146 a = *str++; | |
| 147 b = *str++; | |
| 148 if (!jsY_ishex(a) || !jsY_ishex(b)) | |
| 149 js_urierror(J, "invalid escape sequence"); | |
| 150 c = jsY_tohex(a) << 4 | jsY_tohex(b); | |
| 151 if (!strchr(reserved, c)) | |
| 152 js_putc(J, &sb, c); | |
| 153 else { | |
| 154 js_putc(J, &sb, '%'); | |
| 155 js_putc(J, &sb, a); | |
| 156 js_putc(J, &sb, b); | |
| 157 } | |
| 158 } | |
| 159 } | |
| 160 js_putc(J, &sb, 0); | |
| 161 | |
| 162 js_pushstring(J, sb ? sb->s : ""); | |
| 163 js_endtry(J); | |
| 164 js_free(J, sb); | |
| 165 } | |
| 166 | |
| 167 #define URIRESERVED ";/?:@&=+$," | |
| 168 #define URIALPHA "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ" | |
| 169 #define URIDIGIT "0123456789" | |
| 170 #define URIMARK "-_.!~*'()" | |
| 171 #define URIUNESCAPED URIALPHA URIDIGIT URIMARK | |
| 172 | |
| 173 static void jsB_decodeURI(js_State *J) | |
| 174 { | |
| 175 Decode(J, js_tostring(J, 1), URIRESERVED "#"); | |
| 176 } | |
| 177 | |
| 178 static void jsB_decodeURIComponent(js_State *J) | |
| 179 { | |
| 180 Decode(J, js_tostring(J, 1), ""); | |
| 181 } | |
| 182 | |
| 183 static void jsB_encodeURI(js_State *J) | |
| 184 { | |
| 185 Encode(J, js_tostring(J, 1), URIUNESCAPED URIRESERVED "#"); | |
| 186 } | |
| 187 | |
| 188 static void jsB_encodeURIComponent(js_State *J) | |
| 189 { | |
| 190 Encode(J, js_tostring(J, 1), URIUNESCAPED); | |
| 191 } | |
| 192 | |
| 193 void jsB_init(js_State *J) | |
| 194 { | |
| 195 /* Create the prototype objects here, before the constructors */ | |
| 196 J->Object_prototype = jsV_newobject(J, JS_COBJECT, NULL); | |
| 197 J->Array_prototype = jsV_newobject(J, JS_CARRAY, J->Object_prototype); | |
| 198 J->Function_prototype = jsV_newobject(J, JS_CCFUNCTION, J->Object_prototype); | |
| 199 J->Boolean_prototype = jsV_newobject(J, JS_CBOOLEAN, J->Object_prototype); | |
| 200 J->Number_prototype = jsV_newobject(J, JS_CNUMBER, J->Object_prototype); | |
| 201 J->String_prototype = jsV_newobject(J, JS_CSTRING, J->Object_prototype); | |
| 202 J->Date_prototype = jsV_newobject(J, JS_CDATE, J->Object_prototype); | |
| 203 | |
| 204 J->RegExp_prototype = jsV_newobject(J, JS_CREGEXP, J->Object_prototype); | |
| 205 J->RegExp_prototype->u.r.prog = js_regcompx(J->alloc, J->actx, "(?:)", 0, NULL); | |
| 206 J->RegExp_prototype->u.r.source = js_strdup(J, "(?:)"); | |
| 207 | |
| 208 /* All the native error types */ | |
| 209 J->Error_prototype = jsV_newobject(J, JS_CERROR, J->Object_prototype); | |
| 210 J->EvalError_prototype = jsV_newobject(J, JS_CERROR, J->Error_prototype); | |
| 211 J->RangeError_prototype = jsV_newobject(J, JS_CERROR, J->Error_prototype); | |
| 212 J->ReferenceError_prototype = jsV_newobject(J, JS_CERROR, J->Error_prototype); | |
| 213 J->SyntaxError_prototype = jsV_newobject(J, JS_CERROR, J->Error_prototype); | |
| 214 J->TypeError_prototype = jsV_newobject(J, JS_CERROR, J->Error_prototype); | |
| 215 J->URIError_prototype = jsV_newobject(J, JS_CERROR, J->Error_prototype); | |
| 216 | |
| 217 /* Create the constructors and fill out the prototype objects */ | |
| 218 jsB_initobject(J); | |
| 219 jsB_initarray(J); | |
| 220 jsB_initfunction(J); | |
| 221 jsB_initboolean(J); | |
| 222 jsB_initnumber(J); | |
| 223 jsB_initstring(J); | |
| 224 jsB_initregexp(J); | |
| 225 jsB_initdate(J); | |
| 226 jsB_initerror(J); | |
| 227 jsB_initmath(J); | |
| 228 jsB_initjson(J); | |
| 229 | |
| 230 /* Initialize the global object */ | |
| 231 js_pushnumber(J, NAN); | |
| 232 js_defglobal(J, "NaN", JS_READONLY | JS_DONTENUM | JS_DONTCONF); | |
| 233 | |
| 234 js_pushnumber(J, INFINITY); | |
| 235 js_defglobal(J, "Infinity", JS_READONLY | JS_DONTENUM | JS_DONTCONF); | |
| 236 | |
| 237 js_pushundefined(J); | |
| 238 js_defglobal(J, "undefined", JS_READONLY | JS_DONTENUM | JS_DONTCONF); | |
| 239 | |
| 240 jsB_globalf(J, "parseInt", jsB_parseInt, 1); | |
| 241 jsB_globalf(J, "parseFloat", jsB_parseFloat, 1); | |
| 242 jsB_globalf(J, "isNaN", jsB_isNaN, 1); | |
| 243 jsB_globalf(J, "isFinite", jsB_isFinite, 1); | |
| 244 | |
| 245 jsB_globalf(J, "decodeURI", jsB_decodeURI, 1); | |
| 246 jsB_globalf(J, "decodeURIComponent", jsB_decodeURIComponent, 1); | |
| 247 jsB_globalf(J, "encodeURI", jsB_encodeURI, 1); | |
| 248 jsB_globalf(J, "encodeURIComponent", jsB_encodeURIComponent, 1); | |
| 249 } |
