readme.txt 21 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602
  1. NOTE: This page is also in XOWA under home/wiki/Help:Luaj
  2. == Source ==
  3. The luaj_xowa.jar was built using the source at http://sourceforge.net/projects/luaj/files/luaj-3.0/3.0-beta2/luaj-3.0-beta2.zip/download.
  4. Its source is not currently included with XOWA. It is available at the following location: https://sourceforge.net/projects/xowa/files/support/luaj/
  5. == Modification ==
  6. The luaj_xowa.jar was created for the following reasons:
  7. * Backward compatibility:
  8. : Scribunto is currently using Lua 5.1 whereas luaj 3.0 is designed for Lua 5.2
  9. : Lua 5.2 is not backward-compatible with Lua 5.1; several functions are obsoleted (for example, table.maxn)
  10. : The luaj_xowa.jar was tailored to support Scribunto's 5.1 environment.
  11. * Patches / bug fixes:
  12. : Luaj has a handful of minor issues / defects. They are listed below.
  13. == $engines variable ==
  14. Note that the $engines variable refers to /xowa/bin/any/lua/mediawiki/extensions/Scribunto/engines/
  15. == Luaj changes ==
  16. === Luaj 2.0.3 errors fixed in 3.0 ===
  17. ==== os.time doesn't handle dates before 1970 ====
  18. * fix : incorrect Birth / Date; EX: ru.w:Пушкин,_Александр_Сергеевич
  19. * file: /src/core/org/luaj/vm2/lib/OsLib.java
  20. ==== pairs.next fails when setting val to null ====
  21. * fix : Finnish declension table; EX:d:Latvia
  22. * file: /src/core/org/luaj/vm2/LuaTable.java
  23. === Luaj 2.0.3 features removed from 3.0 ===
  24. ==== string.gfind deprecated ====
  25. * fix : missing Video_game_reviews; EX: w:Sonic_Heroes
  26. * file: /src/core/org/luaj/vm2/lib/StringLib.java
  27. * code: call
  28. <pre>
  29. old:
  30. "sub"} );
  31. new:
  32. "sub", "gfind"} );
  33. </pre>
  34. * code: invoke
  35. <pre>
  36. add:
  37. case 4:
  38. case 9: return StringLib.gmatch( args );
  39. </pre>
  40. ==== math.log10 deprecated ====
  41. * fix : blank references; EX:w:Earth
  42. * file: /src/jse/org/luaj/vm2/lib/JseMathLib.java
  43. * code:
  44. <pre>
  45. math.set("log10", new log10());
  46. static final class log10 extends UnaryOp { protected double call(double d) { return Math.log10(d); } }
  47. </pre>
  48. ==== math.mod deprecated ====
  49. * fix : missing table; EX:d:աղբիւր
  50. * file: /src/core/org/luaj/vm2/lib/MathLib.java
  51. * code:
  52. <pre>
  53. fmod fmod_func = new fmod();
  54. math.set("mod", fmod_func);
  55. math.set("fmod", fmod_func);
  56. </pre>
  57. ==== table.maxn deprecated ====
  58. file: /src/core/org/luaj/vm2/lib/TableLib.java
  59. * code:
  60. <pre>
  61. public LuaValue getn() {
  62. int len = length();
  63. for (int n = len; n > 0; --n )
  64. if ( !rawget(n).isnil() )
  65. return LuaInteger.valueOf(n);
  66. return ZERO;
  67. }
  68. </pre>
  69. file: /src/core/org/luaj/vm2/lib/TableLib.java
  70. <pre>
  71. table.set("maxn", new maxn());
  72. static class maxn extends OneArgFunction {
  73. public LuaValue call(LuaValue arg) {
  74. return LuaValue.valueOf(arg.checktable().maxn());
  75. }
  76. }
  77. </pre>
  78. ==== table.getn deprecated ====
  79. * fix : missing text; EX: d:aceite d:Module:pt-verb-form-of
  80. * file: /src/core/org/luaj/vm2/LuaTable.java
  81. code:
  82. <pre>
  83. public LuaValue getn() {
  84. int len = length();
  85. for (int n = len; n > 0; --n )
  86. if ( !rawget(n).isnil() )
  87. return LuaInteger.valueOf(n);
  88. return ZERO;
  89. }
  90. </pre>
  91. * file: /src/core/org/luaj/vm2/lib/TableLib.java
  92. * code:
  93. <pre>
  94. table.set("getn", new getn());
  95. static class getn extends OneArgFunction {
  96. public LuaValue call(LuaValue arg) {
  97. return arg.checktable().getn();
  98. }
  99. }
  100. </pre>
  101. ==== automatic arg variable in varargs function deprecated ====
  102. * fix : Horizontal timeline; EX: w:Cretaceous%E2%80%93Paleogene_extinction_event
  103. * file: /src/core/org/luaj/vm2/LuaClosure.java
  104. code:
  105. <pre>
  106. case Lua.OP_GETTABUP: /* A B C R(A) := UpValue[B][RK(C)] */
  107. // stack[a] = upValues[i>>>23].getValue().get((c=(i>>14)&0x1ff)>0xff? k[c&0x0ff]: stack[c]);
  108. // HACK: handle deprecated "arg" for "..."
  109. int OP_GETTABUP_c = (i>>14)&0x1ff;
  110. boolean OP_GETTABUP_b = OP_GETTABUP_c>0xff;
  111. LuaValue OP_GETTABUP_idx = OP_GETTABUP_b ? k[OP_GETTABUP_c&0x0ff]: stack[OP_GETTABUP_c];
  112. stack[a] = upValues[i>>>23].getValue().get(OP_GETTABUP_idx);
  113. // HACK: handle deprecated "arg"
  114. if ( p.is_vararg == 1
  115. && stack[a] == NIL
  116. && OP_GETTABUP_b
  117. && "arg".equals(OP_GETTABUP_idx.tojstring())
  118. )
  119. stack[a] = new LuaTable(varargs);
  120. continue;
  121. </pre>
  122. === Luaj 3.0 defects ===
  123. ==== os.date does not accept UTC format ====
  124. * fix : incorrect age in ym; EX:w:Supreme_Court_of_the_United_States
  125. * file: /src/core/org/luaj/vm2/lib/OsLib.java
  126. * proc: invoke.DATE
  127. <pre>
  128. boolean utc = false;
  129. if (s.startsWith("!")) {
  130. utc = true;
  131. s = s.substring(1);
  132. }
  133. if (s.equals("*t")) {
  134. Calendar d = Calendar.getInstance();
  135. long time_in_ms = (long)(t*1000);
  136. if (utc) {
  137. java.util.TimeZone current_tz = d.getTimeZone();
  138. int offset_from_utc = current_tz.getOffset(time_in_ms);
  139. time_in_ms += -offset_from_utc;
  140. }
  141. </pre>
  142. ==== string.gsub fails with out_of_bounds error ====
  143. * fix : blank references; EX:w:Earth
  144. * file: /src/core/org/luaj/vm2/lib/StringLib.java
  145. * proc: gsub
  146. <pre>
  147. old:
  148. if ( anchor )
  149. break;
  150. new:
  151. if ( anchor )
  152. break;
  153. if (soffset >= srclen) break; // assert soffset is in bounds, else will throw ArrayIndexOutOfBounds exception;
  154. </pre>
  155. ==== string.gsub fails if string is empty====
  156. * fix : blank references; EX:w:Woburn,_Massachusetts
  157. * file: /src/core/org/luaj/vm2/lib/StringLib.java
  158. * proc: gsub
  159. <pre>
  160. static Varargs gsub( Varargs args ) {
  161. LuaString src = args.checkstring( 1 );
  162. final int srclen = src.length();
  163. if (srclen == 0) return varargsOf(src, LuaValue.ZERO); // exit early
  164. </pre>
  165. ==== string.format ignores precision for double args ====
  166. * fix : Convert calls will show full precision for numbers; EX:w:Tomato
  167. * file: /src/core/org/luaj/vm2/lib/StringLib.java
  168. <pre>
  169. old:
  170. case 'G':
  171. fdsc.format( result, args.checkdouble( arg ) );
  172. new:
  173. case 'c': // merged c with e E f F g G
  174. fdsc.format( result, fmt.tojstring().substring(i - fdsc.length, i), args.checkdouble( arg ));
  175. </pre>
  176. * proc: format
  177. <pre>
  178. old:
  179. buf.append( v) );
  180. new:
  181. try {
  182. fmtstr = "%" + fmtstr; // % stripped above
  183. buf.append( String.format(fmtstr, v) ); // call String.format
  184. }catch (java.util.MissingFormatWidthException e) {
  185. // HACK: handle invalid format of "%0.1f" -> "%.1f"; %0 should be followed by valid number, but in this case, ignore it;
  186. String old_fmt = e.getFormatSpecifier();
  187. if (old_fmt.startsWith("0")) {
  188. String new_fmt = old_fmt.substring(1); // remove initial 0
  189. fmtstr = fmtstr.replace(old_fmt, new_fmt);
  190. buf.append( String.format(fmtstr, v) ); // call String.format
  191. }
  192. else
  193. throw e;
  194. }
  195. </pre>
  196. * note: forces a 1.5 JRE (as opposed to 1.3)
  197. ==== string.tonumber should trim all whitespace ====
  198. * fix: Population tables; EX: w:Woburn,_Massachusetts
  199. * file: /src/core/org/luaj/vm2/LuaString.java
  200. * proc: scannumber
  201. <pre>
  202. // trim ws
  203. int idx = i;
  204. while (idx < j) {
  205. switch (m_bytes[idx]) {
  206. case 9: case 10: case 13: case 32:
  207. ++idx;
  208. i = idx;
  209. break;
  210. default:
  211. idx = j;
  212. break;
  213. }
  214. }
  215. idx = j - 1;
  216. while (idx >= i) {
  217. switch (m_bytes[idx]) {
  218. case 9: case 10: case 13: case 32:
  219. j = idx;
  220. --idx;
  221. break;
  222. default:
  223. idx = i -1;
  224. break;
  225. }
  226. }
  227. </pre>
  228. ==== multi-byte strings not fully supported ====
  229. * fix : Thai calendar; EX:th.w:เหตุการณ์ปัจจุบัน
  230. * file: /src/core/org/luaj/vm2/LuaString.java
  231. <pre style='overflow:auto'>
  232. public static LuaString valueOf(char[] chars, int off, int len) {
  233. // COMMENTED: does not handle 2+ byte chars; assumes 1 char = 1 byte
  234. // byte[] b = new byte[len];
  235. // for ( int i=0; i<len; i++ )
  236. // b[i] = (byte) chars[i + off];
  237. // return valueOf(b, 0, len);
  238. int bry_len = 0;
  239. for (int i = 0; i < len; i++) // iterate over chars to sum all single / multi-byte chars
  240. bry_len += LuaString.Utf8_len_by_int((int)(chars[i + off]));
  241. byte[] bry = new byte[bry_len];
  242. int bry_idx = 0;
  243. for (int i = 0; i < len; i++) {
  244. int c = (int)(chars[i + off]);
  245. int c_len_in_bytes = LuaString.Utf8_encode_by_int(c, bry, bry_idx);
  246. bry_idx += c_len_in_bytes;
  247. }
  248. return valueOf(bry, 0, bry_len);
  249. }
  250. public static String decodeAsUtf8(byte[] bytes, int offset, int length) {
  251. // COMMENTED: does not handle 3+ byte chars
  252. // int i,j,n,b;
  253. // for ( i=offset,j=offset+length,n=0; i<j; ++n ) {
  254. // switch ( 0xE0 & bytes[i++] ) {
  255. // case 0xE0: ++i;
  256. // case 0xC0: ++i;
  257. // }
  258. // }
  259. // char[] chars=new char[n];
  260. // for ( i=offset,j=offset+length,n=0; i<j; ) {
  261. // chars[n++] = (char) (
  262. // ((b=bytes[i++])>=0||i>=j)? b:
  263. // (b<-32||i+1>=j)? (((b&0x3f) << 6) | (bytes[i++]&0x3f)):
  264. // (((b&0xf) << 12) | ((bytes[i++]&0x3f)<<6) | (bytes[i++]&0x3f)));
  265. // }
  266. // return new String(chars);
  267. return new String(bytes, offset, length, java.nio.charset.Charset.forName("UTF-8"));
  268. }
  269. public static int lengthAsUtf8(char[] chars) {
  270. // COMMENTED: does not handle 3+ byte chars
  271. // int i,b;
  272. // char c;
  273. // for ( i=b=chars.length; --i>=0; )
  274. // if ( (c=chars[i]) >=0x80 )
  275. // b += (c>=0x800)? 2: 1;
  276. // return b;
  277. int len = chars.length;
  278. int rv = 0;
  279. for (int i = 0; i < len; i++)
  280. rv += LuaString.Utf8_len_by_int(chars[i]);
  281. return rv;
  282. }
  283. public static int encodeToUtf8(char[] chars, int nchars, byte[] bytes, int off) {
  284. // COMMENTED: does not handle 4+ byte chars; already using Encode_by_int, so might as well be consistent
  285. // char c;
  286. // int j = off;
  287. // for ( int i=0; i<nchars; i++ ) {
  288. // if ( (c = chars[i]) < 0x80 ) {
  289. // bytes[j++] = (byte) c;
  290. // } else if ( c < 0x800 ) {
  291. // bytes[j++] = (byte) (0xC0 | ((c>>6) & 0x1f));
  292. // bytes[j++] = (byte) (0x80 | ( c & 0x3f));
  293. // } else {
  294. // bytes[j++] = (byte) (0xE0 | ((c>>12) & 0x0f));
  295. // bytes[j++] = (byte) (0x80 | ((c>>6) & 0x3f));
  296. // bytes[j++] = (byte) (0x80 | ( c & 0x3f));
  297. // }
  298. // }
  299. // return j - off;
  300. int bry_idx = off;
  301. for (int i = 0; i < nchars; i++ ) {
  302. int c = chars[i];
  303. int c_len_in_bytes = LuaString.Utf8_encode_by_int(c, bytes, bry_idx);
  304. bry_idx += c_len_in_bytes;
  305. }
  306. return nchars; // NOTE: code returned # of bytes which is wrong; Globals.UTF8Stream.read caches rv as j which is used as index to char[] not byte[]; will throw out of bounds exception if bytes returned
  307. }
  308. public static int Utf8_len_by_int(int charAsInt) {
  309. if (charAsInt < 0x80) return 1;
  310. else if (charAsInt < (1 << 11)) return 2;
  311. else if (charAsInt < (1 << 16)) return 3;
  312. else if (charAsInt < (1 << 21)) return 4;
  313. else if (charAsInt < (1 << 26)) return 5;
  314. else return 6;
  315. }
  316. public static int Utf8_len_by_byte(byte b) {
  317. int i = b & 0xff;
  318. switch (i) {
  319. case 0: case 1: case 2: case 3: case 4: case 5: case 6: case 7: case 8: case 9: case 10: case 11: case 12: case 13: case 14: case 15:
  320. case 16: case 17: case 18: case 19: case 20: case 21: case 22: case 23: case 24: case 25: case 26: case 27: case 28: case 29: case 30: case 31:
  321. case 32: case 33: case 34: case 35: case 36: case 37: case 38: case 39: case 40: case 41: case 42: case 43: case 44: case 45: case 46: case 47:
  322. case 48: case 49: case 50: case 51: case 52: case 53: case 54: case 55: case 56: case 57: case 58: case 59: case 60: case 61: case 62: case 63:
  323. case 64: case 65: case 66: case 67: case 68: case 69: case 70: case 71: case 72: case 73: case 74: case 75: case 76: case 77: case 78: case 79:
  324. case 80: case 81: case 82: case 83: case 84: case 85: case 86: case 87: case 88: case 89: case 90: case 91: case 92: case 93: case 94: case 95:
  325. case 96: case 97: case 98: case 99: case 100: case 101: case 102: case 103: case 104: case 105: case 106: case 107: case 108: case 109: case 110: case 111:
  326. case 112: case 113: case 114: case 115: case 116: case 117: case 118: case 119: case 120: case 121: case 122: case 123: case 124: case 125: case 126: case 127:
  327. case 128: case 129: case 130: case 131: case 132: case 133: case 134: case 135: case 136: case 137: case 138: case 139: case 140: case 141: case 142: case 143:
  328. case 144: case 145: case 146: case 147: case 148: case 149: case 150: case 151: case 152: case 153: case 154: case 155: case 156: case 157: case 158: case 159:
  329. case 160: case 161: case 162: case 163: case 164: case 165: case 166: case 167: case 168: case 169: case 170: case 171: case 172: case 173: case 174: case 175:
  330. case 176: case 177: case 178: case 179: case 180: case 181: case 182: case 183: case 184: case 185: case 186: case 187: case 188: case 189: case 190: case 191:
  331. return 1;
  332. case 192: case 193: case 194: case 195: case 196: case 197: case 198: case 199: case 200: case 201: case 202: case 203: case 204: case 205: case 206: case 207:
  333. case 208: case 209: case 210: case 211: case 212: case 213: case 214: case 215: case 216: case 217: case 218: case 219: case 220: case 221: case 222: case 223:
  334. return 2;
  335. case 224: case 225: case 226: case 227: case 228: case 229: case 230: case 231: case 232: case 233: case 234: case 235: case 236: case 237: case 238: case 239:
  336. return 3;
  337. case 240: case 241: case 242: case 243: case 244: case 245: case 246: case 247:
  338. return 4;
  339. case 248: case 249: case 250: case 251:
  340. return 5;
  341. case 252: case 253:
  342. return 6;
  343. case 254: case 255:
  344. default:
  345. return 6;
  346. }
  347. }
  348. public static int Utf8_decode_to_int(byte[] ary, int pos) {
  349. byte b0 = ary[pos];
  350. if ((b0 & 0x80) == 0) {
  351. return b0;
  352. }
  353. else if ((b0 & 0xE0) == 0xC0) {
  354. return ( b0 & 0x1f) << 6
  355. | ( ary[pos + 1] & 0x3f)
  356. ;
  357. }
  358. else if ((b0 & 0xF0) == 0xE0) {
  359. return ( b0 & 0x0f) << 12
  360. | ((ary[pos + 1] & 0x3f) << 6)
  361. | ( ary[pos + 2] & 0x3f)
  362. ;
  363. }
  364. else if ((b0 & 0xF8) == 0xF0) {
  365. return ( b0 & 0x07) << 18
  366. | ((ary[pos + 1] & 0x3f) << 12)
  367. | ((ary[pos + 2] & 0x3f) << 6)
  368. | ( ary[pos + 3] & 0x3f)
  369. ;
  370. }
  371. else if ((b0 & 0xFC) == 0xF8) {
  372. return ( b0 & 0x03) << 24
  373. | ((ary[pos + 1] & 0x3f) << 18)
  374. | ((ary[pos + 2] & 0x3f) << 12)
  375. | ((ary[pos + 3] & 0x3f) << 6)
  376. | ( ary[pos + 4] & 0x3f)
  377. ;
  378. }
  379. else if ((b0 & 0xFC) == 0xFC) {
  380. return ( b0 & 0x03) << 30
  381. | ((ary[pos + 1] & 0x3f) << 24)
  382. | ((ary[pos + 2] & 0x3f) << 18)
  383. | ((ary[pos + 3] & 0x3f) << 12)
  384. | ((ary[pos + 4] & 0x3f) << 6)
  385. | ( ary[pos + 5] & 0x3f)
  386. ;
  387. }
  388. else {
  389. return b0 & 0xFF;
  390. }
  391. }
  392. public static int Utf8_encode_by_int(int charAsInt, byte[] src, int pos) {
  393. if (charAsInt < 0x80) {
  394. src[pos] = (byte)charAsInt;
  395. return 1;
  396. }
  397. else if (charAsInt < (1 << 11)) {
  398. src[pos] = (byte)(0xC0 | (charAsInt >> 6));
  399. src[++pos] = (byte)(0x80 | (charAsInt & 0x3F));
  400. return 2;
  401. }
  402. else if (charAsInt < (1 << 16)) {
  403. src[pos] = (byte)(0xE0 | (charAsInt >> 12));
  404. src[++pos] = (byte)(0x80 | (charAsInt >> 6) & 0x3F);
  405. src[++pos] = (byte)(0x80 | (charAsInt & 0x3F));
  406. return 3;
  407. }
  408. else if (charAsInt < (1 << 21)) {
  409. src[pos] = (byte)(0xF0 | (charAsInt >> 18));
  410. src[++pos] = (byte)(0x80 | (charAsInt >> 12) & 0x3F);
  411. src[++pos] = (byte)(0x80 | (charAsInt >> 6) & 0x3F);
  412. src[++pos] = (byte)(0x80 | (charAsInt & 0x3F));
  413. return 4;
  414. }
  415. else if (charAsInt < (1 << 26)) {
  416. src[pos] = (byte)(0xF8 | (charAsInt >> 24));
  417. src[++pos] = (byte)(0x80 | (charAsInt >> 18) & 0x3F);
  418. src[++pos] = (byte)(0x80 | (charAsInt >> 12) & 0x3F);
  419. src[++pos] = (byte)(0x80 | (charAsInt >> 6) & 0x3F);
  420. src[++pos] = (byte)(0x80 | (charAsInt & 0x3F));
  421. return 5;
  422. }
  423. else if (charAsInt < (1 << 31)) {
  424. src[pos] = (byte)(0xFC | (charAsInt >> 30));
  425. src[++pos] = (byte)(0x80 | (charAsInt >> 24) & 0x3F);
  426. src[++pos] = (byte)(0x80 | (charAsInt >> 18) & 0x3F);
  427. src[++pos] = (byte)(0x80 | (charAsInt >> 12) & 0x3F);
  428. src[++pos] = (byte)(0x80 | (charAsInt >> 6) & 0x3F);
  429. src[++pos] = (byte)(0x80 | (charAsInt & 0x3F));
  430. return 6;
  431. }
  432. else if (charAsInt == 0) {
  433. src[pos] = (byte)0xC0;
  434. src[++pos] = (byte)0x80;
  435. return -1;
  436. }
  437. return -1;
  438. }
  439. </pre>
  440. * file: /src/core/org/luaj/vm2/compiler/LexState.java
  441. * proc: read_string
  442. <pre style='overflow:auto'>
  443. if (c > UCHAR_MAX)
  444. lexerror("escape sequence too large", TK_STRING);
  445. save(c, false); // NOTE: specify that c is integer and does not need conversion; EX: \128 -> 128 -> (char)128, not Utf8_encode(128)
  446. </pre>
  447. * file: /src/core/org/luaj/vm2/compiler/LexState.java
  448. <pre style='overflow:auto'>
  449. void save(int c) {save(c, true);}
  450. void save(int c, boolean c_might_be_utf8) {
  451. int bytes_len = c_might_be_utf8 ? LuaString.Utf8_len_by_byte((byte)c) : 1;
  452. if (bytes_len > 1) { // c is 1st byte of utf8 multi-byte sequence; read required number of bytes and convert to char; EX: ← is serialized in z as 226,134,144; c is currently 226; read 134 and 144 and convert to ←
  453. temp_bry[0] = (byte)c;
  454. for (int i = 1; i < bytes_len; i++) {
  455. nextChar();
  456. temp_bry[i] = (byte)current;
  457. }
  458. c = LuaString.Utf8_decode_to_int(temp_bry, 0);
  459. }
  460. if ( buff == null || nbuff + 1 > buff.length )
  461. buff = LuaC.realloc( buff, nbuff*2+1 );
  462. buff[nbuff++] = (char)c;
  463. }
  464. private static byte[] temp_bry = new byte[6];
  465. </pre>
  466. === build.xml ===
  467. * note: this change is needed to get luaj to compile with the String.format(String, double) call
  468. * file: build.xml
  469. <pre>
  470. old:
  471. <javac destdir="build/jme/classes" encoding="utf-8" source="1.3" target="1.2" bootclasspathref="wtk-libs"
  472. srcdir="build/jme/src"/>
  473. <javac destdir="build/jse/classes" encoding="utf-8" source="1.3" target="1.3"
  474. classpath="lib/bcel-5.2.jar"
  475. srcdir="build/jse/src"
  476. excludes="**/script/*,**/Lua2Java*,lua*"/>
  477. <javac destdir="build/jse/classes" encoding="utf-8" source="1.5" target="1.5"
  478. classpath="build/jse/classes"
  479. srcdir="build/jse/src"
  480. includes="**/script/*,**/Lua2Java*"/>
  481. <javac destdir="build/jse/classes" encoding="utf-8" source="1.3" target="1.3"
  482. classpath="build/jse/classes"
  483. srcdir="build/jse/src"
  484. includes="lua*"/>
  485. new:
  486. <javac destdir="build/jse/classes" encoding="utf-8" source="1.5" target="1.5"
  487. classpath="lib/bcel-5.2.jar"
  488. srcdir="build/jse/src"
  489. excludes="**/script/*,**/Lua2Java*,lua*"/>
  490. <javac destdir="build/jse/classes" encoding="utf-8" source="1.5" target="1.5"
  491. classpath="build/jse/classes"
  492. srcdir="build/jse/src"
  493. includes="**/script/*,**/Lua2Java*"/>
  494. <javac destdir="build/jse/classes" encoding="utf-8" source="1.5" target="1.5"
  495. classpath="build/jse/classes"
  496. srcdir="build/jse/src"
  497. includes="lua*"/>
  498. </pre>
  499. === Luaj tests ===
  500. <pre>
  501. package org.luaj.vm2;
  502. import org.luaj.vm2.lib.StringLib;
  503. import junit.framework.*;
  504. public class Xowa_tst extends TestCase {
  505. private Xowa_fxt fxt = new Xowa_fxt();
  506. public void test_tonumber_ws() {
  507. fxt.Test_tonumber_int("123" , 123);
  508. fxt.Test_tonumber_int("\t\n\r 123\t\n\r" , 123);
  509. fxt.Test_tonumber_nil("1a");
  510. fxt.Test_tonumber_nil("1 2");
  511. fxt.Test_tonumber_nil("");
  512. fxt.Test_tonumber_nil("\t\n\r \t\n\r");
  513. }
  514. public void test_gsub() {
  515. fxt.Test_gsub("abc", "a", "A", "Abc"); // basic
  516. fxt.Test_gsub("a#b", "#", "", "ab"); // match() fails when shortening string
  517. fxt.Test_gsub("", "%b<>", "A", ""); // balance() fails with out of index when find is blank
  518. }
  519. public void test_format() {
  520. fxt.Test_format("%.1f" , "1.23", "1.2"); // apply precision; 1 decimal place
  521. fxt.Test_format("(%.1f)", "1.23", "(1.2)"); // handle substring; format_string should be "%.1f" not "(%.1f)"
  522. fxt.Test_format("%0.1f" , "1.23", "1.2"); // handle invalid precision of 0
  523. }
  524. }
  525. class Xowa_fxt {
  526. public void Test_tonumber_int(String raw, int expd) {
  527. LuaString actl_str = LuaString.valueOf(raw);
  528. LuaInteger actl_int = (LuaInteger)actl_str.tonumber();
  529. Assert.assertEquals(expd, actl_int.v);
  530. }
  531. public void Test_tonumber_nil(String raw) {
  532. LuaString actl_str = LuaString.valueOf(raw);
  533. Assert.assertEquals(LuaValue.NIL, actl_str.tonumber());
  534. }
  535. public void Test_gsub(String text, String regx, String repl, String expd) {
  536. Varargs actl_args = StringLib.gsub_test(LuaValue.varargsOf(new LuaValue[] {LuaValue.valueOf(text), LuaValue.valueOf(regx), LuaValue.valueOf(repl)}));
  537. Assert.assertEquals(expd, actl_args.checkstring(1).tojstring());
  538. }
  539. public void Test_format(String fmt, String val, String expd) {
  540. Varargs actl_args = StringLib.format_test(LuaValue.varargsOf(new LuaValue[] {LuaValue.valueOf(fmt), LuaValue.valueOf(val)}));
  541. Assert.assertEquals(expd, actl_args.checkstring(1).tojstring());
  542. }
  543. }
  544. </pre>
  545. == Scribunto related ==
  546. None of these changes affect the luaj_xowa.jar. They are noted for comprehensiveness's sake.
  547. === getfenv/setfenv deprecated ===
  548. * add lua-compat-env
  549. : source: https://github.com/davidm/lua-compat-env
  550. : target: $engines/LuaCommon/lualib/lua-compat-env .lua
  551. * add alias to $engines/Luaj/mw_main.lua
  552. : _G.getfenv = require 'compat_env'.getfenv
  553. : _G.setfenv = require 'compat_env'.setfenv
  554. * change xowa.jar to load debugLibrary
  555. : Globals.load(new DebugLib());
  556. === loadString deprecated ===
  557. * add alias to $engines/Luaj/mw_main.lua
  558. : _G.loadstring = load
  559. === table.unpack deprecated ===
  560. * add alias to $engines/Luaj/mw_main.lua
  561. : _G.unpack = table.unpack