1
0
mirror of https://github.com/gnosygnu/xowa.git synced 2026-03-02 03:49:30 +00:00

'v3.7.4.1'

This commit is contained in:
gnosygnu
2016-07-25 21:59:51 -04:00
parent 7a851a41a5
commit 8e91ac0bc4
175 changed files with 2079 additions and 933 deletions

View File

@@ -43,8 +43,7 @@ public class Pf_func_ {
nde.Val_tkn().Tmpl_evaluate(ctx, src, caller, bfr);
return bfr.To_bry_and_clear_and_trim();
}
private static final Number_parser lhs_parser = new Number_parser().Hex_enabled_(true), rhs_parser = new Number_parser().Hex_enabled_(true);
public static boolean Eq_(byte[] lhs, byte[] rhs) { // PATCH.PHP: php allows "003" == "3.0"; ASSUME: numbers are either int or int-like decimal; long, float, decimal not supported
public static boolean Eq(Xop_ctx ctx, byte[] lhs, byte[] rhs) { // PATCH.PHP: php allows "003" == "3.0"; ASSUME: numbers are either int or int-like decimal; long, float, decimal not supported
int lhs_len = lhs.length, rhs_len = rhs.length;
boolean rv = true;
if (lhs_len == rhs_len) {
@@ -58,13 +57,13 @@ public class Pf_func_ {
}
else if (lhs_len == 0 || rhs_len == 0) // one side is empty String and the other side is String; return false;
return false;
synchronized (lhs_parser) { // LOCK:static-obj; DATE:2016-07-06
lhs_parser.Parse(lhs, 0, lhs_len);
if (lhs_parser.Has_err()) return false;
rhs_parser.Parse(rhs, 0, rhs_len);
if (rhs_parser.Has_err()) return false;
return lhs_parser.Has_frac() || rhs_parser.Has_frac() ? lhs_parser.Rv_as_dec().Eq(rhs_parser.Rv_as_dec()) : lhs_parser.Rv_as_int() == rhs_parser.Rv_as_int();
}
Number_parser lhs_parser = ctx.Tmp_mgr().Pfunc_num_parser_0();
Number_parser rhs_parser = ctx.Tmp_mgr().Pfunc_num_parser_1();
lhs_parser.Parse(lhs, 0, lhs_len);
if (lhs_parser.Has_err()) return false;
rhs_parser.Parse(rhs, 0, rhs_len);
if (rhs_parser.Has_err()) return false;
return lhs_parser.Has_frac() || rhs_parser.Has_frac() ? lhs_parser.Rv_as_dec().Eq(rhs_parser.Rv_as_dec()) : lhs_parser.Rv_as_int() == rhs_parser.Rv_as_int();
}
public static void Reg(Xow_domain_itm domain_itm, gplx.xowa.langs.funcs.Xol_func_regy func_regy, Xol_lang_itm lang) {
Xol_kwd_mgr kwd_mgr = lang.Kwd_mgr();

View File

@@ -16,25 +16,24 @@ You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package gplx.xowa.xtns.pfuncs.exprs; import gplx.*; import gplx.xowa.*; import gplx.xowa.xtns.*; import gplx.xowa.xtns.pfuncs.*;
import gplx.xowa.parsers.*;
class Func_tkn_stack {
public void Clear() {stack_len = 0;}
public int Len() {return stack_len;}
public Func_tkn GetLast() {return stack_len == 0 ? null : stack[stack_len - 1];}
private Func_tkn[] ary = new Func_tkn[0]; private int len = 0, max = 0;
public void Clear() {len = 0;}
public int Len() {return len;}
public Func_tkn Get_at_last() {return len == 0 ? null : ary[len - 1];}
public Func_tkn Pop() {
int stack_len_new = stack_len - 1;
Func_tkn rv = stack[stack_len_new];
stack_len = stack_len_new;
int new_len = len - 1;
Func_tkn rv = ary[new_len];
len = new_len;
return rv;
}
public void Push(Func_tkn v) {
int stack_len_new = stack_len + 1;
if (stack_len_new > stack_max) {
stack_max = stack_len_new * 2;
stack = (Func_tkn[])Array_.Resize(stack, stack_max);
int new_len = len + 1;
if (new_len > max) {
max = new_len * 2;
ary = (Func_tkn[])Array_.Resize(ary, max);
}
stack[stack_len] = v;
stack_len = stack_len_new;
ary[len] = v;
len = new_len;
}
Func_tkn[] stack = new Func_tkn[0]; int stack_len = 0, stack_max = 0;
}

View File

@@ -25,6 +25,7 @@ public class Pfunc_expr extends Pf_func_base {
Evaluate(bfr, ctx, val_dat_ary);
}
public static boolean Evaluate(Bry_bfr bfr, Xop_ctx ctx, byte[] expr) {
Pfunc_expr_shunter shunter = ctx.Tmp_mgr().Expr_shunter();
Decimal_adp rslt = shunter.Evaluate(ctx, expr); // NOTE: php uses "float" but really is a double; http://www.php.net/manual/en/language.types.float.php
if (rslt == Pfunc_expr_shunter.Null_rslt) {
bfr.Add_bfr_and_preserve(shunter.Err());
@@ -36,11 +37,10 @@ public class Pfunc_expr extends Pf_func_base {
return true;
}
}
private static Pfunc_expr_shunter shunter = Pfunc_expr_shunter.Instance;
@Override public int Id() {return Xol_kwd_grp_.Id_xtn_expr;}
@Override public Pf_func New(int id, byte[] name) {return new Pfunc_expr().Name_(name);}
}
class Pfunc_expr_msg {
public static final Gfo_msg_grp Nde = Gfo_msg_grp_.new_(Xoa_app_.Nde, "expr");
public static final Gfo_msg_itm Unknown = Gfo_msg_itm_.new_warn_(Nde, "unknown", "unknown");
public static final Gfo_msg_grp Nde = Gfo_msg_grp_.new_(Xoa_app_.Nde, "expr");
public static final Gfo_msg_itm Unknown = Gfo_msg_itm_.new_warn_(Nde, "unknown", "unknown");
}

View File

@@ -20,12 +20,11 @@ import gplx.core.btries.*; import gplx.core.brys.fmtrs.*;
import gplx.xowa.langs.*; import gplx.xowa.langs.msgs.*;
import gplx.xowa.parsers.*;
public class Pfunc_expr_shunter {
private Btrie_fast_mgr trie = expression_(); private final Btrie_rv trv = new Btrie_rv();
Val_stack val_stack = new Val_stack();
Func_tkn_stack prc_stack = new Func_tkn_stack();
public static final Decimal_adp Null_rslt = null;
private final Object thread_lock = new Object();
public Bry_bfr Err() {return err_bfr;} Bry_bfr err_bfr = Bry_bfr_.New();
private final Btrie_fast_mgr trie = expression_(); private final Btrie_rv trv = new Btrie_rv();
private final Val_stack val_stack = new Val_stack();
private final Func_tkn_stack prc_stack = new Func_tkn_stack();
private final Bry_fmtr tmp_fmtr = Bry_fmtr.tmp_();
public Bry_bfr Err() {return err_bfr;} private final Bry_bfr err_bfr = Bry_bfr_.New();
public Decimal_adp Err_set(Xop_ctx ctx, int msgId) {return Err_set(ctx, msgId, Bry_.Empty);}
public Decimal_adp Err_set(Xop_ctx ctx, int msg_id, byte[] arg) {
byte[] msg_val = ctx.Wiki().Msg_mgr().Val_by_id(msg_id);
@@ -33,136 +32,137 @@ public class Pfunc_expr_shunter {
tmp_fmtr.Fmt_(msg_val).Bld_bfr_one(err_bfr, arg);
err_bfr.Add(Err_end_ary);
return Null_rslt;
} static final byte[] Err_bgn_ary = Bry_.new_a7("<strong class=\"error\">"), Err_end_ary = Bry_.new_a7("</strong>"); Bry_fmtr tmp_fmtr = Bry_fmtr.tmp_();
}
public void Rslt_set(byte[] bry) {
err_bfr.Add(bry);
}
public Decimal_adp Evaluate(Xop_ctx ctx, byte[] src) { // REF.MW: Expr.php
synchronized (thread_lock) {
int src_len = src.length; if (src_len == 0) return Null_rslt;
int cur_pos = 0; byte cur_byt = src[0];
boolean mode_expr = true; Func_tkn prv_prc = null;
val_stack.Clear(); prc_stack.Clear();
while (true) {
// can't think of a way for this to happen; note that operators will automatically push values/operators off stack that are lower; can't get up to 100
// if (val_stack.Len() > 100 || prc_stack.Len() > 100) return Err_set(ctx, Xol_msg_itm_.Id_pfunc_expr_err__stack_exhausted);
Object o = trie.Match_at_w_b0(trv, cur_byt, src, cur_pos, src_len);
int bgn_pos = cur_pos;
if (o == null) { // letter or unknown symbol
while (cur_pos < src_len) {
byte b = src[cur_pos++];
if (Byte_ascii.Is_ltr(b))
continue;
else
break;
}
return Err_set(ctx, Xol_msg_itm_.Id_pfunc_expr_unrecognised_word, Bry_.Mid(src, bgn_pos, cur_pos));
int src_len = src.length; if (src_len == 0) return Null_rslt;
int cur_pos = 0; byte cur_byt = src[0];
boolean mode_expr = true; Func_tkn prv_prc = null;
val_stack.Clear(); prc_stack.Clear();
while (true) {
// can't think of a way for this to happen; note that operators will automatically push values/operators off stack that are lower; can't get up to 100
// if (val_stack.Len() > 100 || prc_stack.Len() > 100) return Err_set(ctx, Xol_msg_itm_.Id_pfunc_expr_err__stack_exhausted);
Object o = trie.Match_at_w_b0(trv, cur_byt, src, cur_pos, src_len);
int bgn_pos = cur_pos;
if (o == null) { // letter or unknown symbol
while (cur_pos < src_len) {
byte b = src[cur_pos++];
if (Byte_ascii.Is_ltr(b))
continue;
else
break;
}
else {
Expr_tkn t = (Expr_tkn)o;
cur_pos = trv.Pos();
switch (t.Tid()) {
case Expr_tkn_.Tid_space: break;
case Expr_tkn_.Tid_number:
if (!mode_expr) return Err_set(ctx, Xol_msg_itm_.Id_pfunc_expr_unexpected_number);
int numBgn = cur_pos - 1;
boolean loop = true;
while (loop) {
if (cur_pos == src_len) break;
switch (src[cur_pos]) {
case Byte_ascii.Num_0: case Byte_ascii.Num_1: case Byte_ascii.Num_2: case Byte_ascii.Num_3: case Byte_ascii.Num_4:
case Byte_ascii.Num_5: case Byte_ascii.Num_6: case Byte_ascii.Num_7: case Byte_ascii.Num_8: case Byte_ascii.Num_9:
case Byte_ascii.Dot:
++cur_pos;
break;
default: loop = false; break;
}
return Err_set(ctx, Xol_msg_itm_.Id_pfunc_expr_unrecognised_word, Bry_.Mid(src, bgn_pos, cur_pos));
}
else {
Expr_tkn t = (Expr_tkn)o;
cur_pos = trv.Pos();
switch (t.Tid()) {
case Expr_tkn_.Tid_space: break;
case Expr_tkn_.Tid_number:
if (!mode_expr) return Err_set(ctx, Xol_msg_itm_.Id_pfunc_expr_unexpected_number);
int numBgn = cur_pos - 1;
boolean loop = true;
while (loop) {
if (cur_pos == src_len) break;
switch (src[cur_pos]) {
case Byte_ascii.Num_0: case Byte_ascii.Num_1: case Byte_ascii.Num_2: case Byte_ascii.Num_3: case Byte_ascii.Num_4:
case Byte_ascii.Num_5: case Byte_ascii.Num_6: case Byte_ascii.Num_7: case Byte_ascii.Num_8: case Byte_ascii.Num_9:
case Byte_ascii.Dot:
++cur_pos;
break;
default: loop = false; break;
}
Decimal_adp num = Null_rslt;
try {num = Bry_.To_decimal(src, numBgn, cur_pos);}
catch (Exception exc) {
// NOTE: PATCH.PHP: 65.5.5 can evaluate to 65.5; EX "{{Geological eras|-600|height=2|border=none}}" eventually does "|10-to={{#ifexpr:{{{1|-4567}}}<-65.5|-65.5|{{{1}}}}}.5" which is 65.5.5
Err_.Noop(exc);
int dot_count = 0;
for (int i = numBgn; i < cur_pos; i++) {
if (src[i] == Byte_ascii.Dot) {
switch (dot_count) {
case 0: dot_count = 1; break;
case 1:
try {
num = Bry_.To_decimal(src, numBgn, i);
}
catch (Exception exc_inner) {Err_.Noop(exc_inner);}
break;
}
}
Decimal_adp num = Null_rslt;
try {num = Bry_.To_decimal(src, numBgn, cur_pos);}
catch (Exception exc) {
// NOTE: PATCH.PHP: 65.5.5 can evaluate to 65.5; EX "{{Geological eras|-600|height=2|border=none}}" eventually does "|10-to={{#ifexpr:{{{1|-4567}}}<-65.5|-65.5|{{{1}}}}}.5" which is 65.5.5
Err_.Noop(exc);
int dot_count = 0;
for (int i = numBgn; i < cur_pos; i++) {
if (src[i] == Byte_ascii.Dot) {
switch (dot_count) {
case 0: dot_count = 1; break;
case 1:
try {
num = Bry_.To_decimal(src, numBgn, i);
}
catch (Exception exc_inner) {Err_.Noop(exc_inner);}
break;
}
}
if (num == null) return Null_rslt;
}
val_stack.Push(num);
mode_expr = false;
break;
case Expr_tkn_.Tid_paren_lhs:
if (!mode_expr) return Err_set(ctx, Xol_msg_itm_.Id_pfunc_expr_unexpected_operator, Bry_.new_a7("("));
prc_stack.Push((Func_tkn)t);
break;
case Expr_tkn_.Tid_operator:
Func_tkn cur_prc = (Func_tkn)t;
if (Byte_ascii.Is_ltr(cur_byt)) {
int nxt_pos = Bry_find_.Find_fwd_while_letter(src, cur_pos, src_len);
if (nxt_pos > cur_pos)
return Err_set(ctx, Xol_msg_itm_.Id_pfunc_expr_unrecognised_word, Bry_.Mid(src, bgn_pos, nxt_pos));
}
if (cur_prc.Func_is_const()) { // func is "pi" or "e"; DATE:2014-03-01
if (mode_expr) { // number expected; just call Calc (which will place value on stack)
cur_prc.Calc(ctx, this, val_stack);
break;
}
else // operator expected; fail b/c pi / e is not an operator;
return Err_set(ctx, Xol_msg_itm_.Id_pfunc_expr_unexpected_number);
}
if (mode_expr) { // NOTE: all the GetAlts have higher precedence; "break;" need to skip evaluation below else will fail for --1
Func_tkn alt_prc = cur_prc.GetAlt();
prc_stack.Push(alt_prc);
if (num == null) return Null_rslt;
}
val_stack.Push(num);
mode_expr = false;
break;
case Expr_tkn_.Tid_paren_lhs:
if (!mode_expr) return Err_set(ctx, Xol_msg_itm_.Id_pfunc_expr_unexpected_operator, Bry_.new_a7("("));
prc_stack.Push((Func_tkn)t);
break;
case Expr_tkn_.Tid_operator:
Func_tkn cur_prc = (Func_tkn)t;
if (Byte_ascii.Is_ltr(cur_byt)) {
int nxt_pos = Bry_find_.Find_fwd_while_letter(src, cur_pos, src_len);
if (nxt_pos > cur_pos)
return Err_set(ctx, Xol_msg_itm_.Id_pfunc_expr_unrecognised_word, Bry_.Mid(src, bgn_pos, nxt_pos));
}
if (cur_prc.Func_is_const()) { // func is "pi" or "e"; DATE:2014-03-01
if (mode_expr) { // number expected; just call Calc (which will place value on stack)
cur_prc.Calc(ctx, this, val_stack);
break;
}
prv_prc = prc_stack.GetLast();
while (prv_prc != null && (cur_prc.Precedence() <= prv_prc.Precedence())) {
if (!prv_prc.Calc(ctx, this, val_stack)) return Null_rslt;
prc_stack.Pop();
prv_prc = prc_stack.GetLast();
}
prc_stack.Push(cur_prc);
mode_expr = true;
break;
case Expr_tkn_.Tid_paren_rhs: {
prv_prc = prc_stack.GetLast();
while (prv_prc != null && prv_prc.Tid() != Expr_tkn_.Tid_paren_lhs) {
if (!prv_prc.Calc(ctx, this, val_stack)) return Null_rslt;
prc_stack.Pop();
prv_prc = prc_stack.GetLast();
}
if (prv_prc == Paren_bgn_tkn.Instance)
prc_stack.Pop();
else
return Err_set(ctx, Xol_msg_itm_.Id_pfunc_expr_unexpected_closing_bracket);
mode_expr = false;
else // operator expected; fail b/c pi / e is not an operator;
return Err_set(ctx, Xol_msg_itm_.Id_pfunc_expr_unexpected_number);
}
if (mode_expr) { // NOTE: all the GetAlts have higher precedence; "break;" need to skip evaluation below else will fail for --1
Func_tkn alt_prc = cur_prc.GetAlt();
prc_stack.Push(alt_prc);
break;
}
prv_prc = prc_stack.Get_at_last();
while (prv_prc != null && (cur_prc.Precedence() <= prv_prc.Precedence())) {
if (!prv_prc.Calc(ctx, this, val_stack)) return Null_rslt;
prc_stack.Pop();
prv_prc = prc_stack.Get_at_last();
}
prc_stack.Push(cur_prc);
mode_expr = true;
break;
case Expr_tkn_.Tid_paren_rhs: {
prv_prc = prc_stack.Get_at_last();
while (prv_prc != null && prv_prc.Tid() != Expr_tkn_.Tid_paren_lhs) {
if (!prv_prc.Calc(ctx, this, val_stack)) return Null_rslt;
prc_stack.Pop();
prv_prc = prc_stack.Get_at_last();
}
if (prv_prc == Paren_bgn_tkn.Instance)
prc_stack.Pop();
else
return Err_set(ctx, Xol_msg_itm_.Id_pfunc_expr_unexpected_closing_bracket);
mode_expr = false;
break;
}
}
if (cur_pos == src_len) break;
cur_byt = src[cur_pos];
}
while (prc_stack.Len() > 0) {
Func_tkn cur_prc = prc_stack.Pop();
if (cur_prc.Tid() == Expr_tkn_.Tid_paren_lhs) return Err_set(ctx, Xol_msg_itm_.Id_pfunc_expr_unclosed_bracket);
if (!cur_prc.Calc(ctx, this, val_stack)) return Null_rslt;
}
return val_stack.Len() == 0 ? Null_rslt : val_stack.Pop(); // HACK: for [[List of Premiers of South Australia by time in office]] and {{#expr:\n{{age in days
if (cur_pos == src_len) break;
cur_byt = src[cur_pos];
}
while (prc_stack.Len() > 0) {
Func_tkn cur_prc = prc_stack.Pop();
if (cur_prc.Tid() == Expr_tkn_.Tid_paren_lhs) return Err_set(ctx, Xol_msg_itm_.Id_pfunc_expr_unclosed_bracket);
if (!cur_prc.Calc(ctx, this, val_stack)) return Null_rslt;
}
return val_stack.Len() == 0 ? Null_rslt : val_stack.Pop(); // HACK: for [[List of Premiers of South Australia by time in office]] and {{#expr:\n{{age in days
}
private static Btrie_fast_mgr expression_() {
public static final Decimal_adp Null_rslt = null;
private static Btrie_fast_mgr expression_() { // changed to instance; DATE:2016-07-20
Btrie_fast_mgr rv = Btrie_fast_mgr.ci_a7(); // NOTE:ci.ascii:MW_const.en; math and expressions
Trie_add(rv, new Ws_tkn(Byte_ascii.Space));
Trie_add(rv, new Ws_tkn(Byte_ascii.Tab));
@@ -221,5 +221,5 @@ public class Pfunc_expr_shunter {
return rv;
}
private static void Trie_add(Btrie_fast_mgr trie, Expr_tkn tkn) {trie.Add(tkn.Val_ary(), tkn);}
public static final Pfunc_expr_shunter Instance = new Pfunc_expr_shunter(); Pfunc_expr_shunter() {}
private static final byte[] Err_bgn_ary = Bry_.new_a7("<strong class=\"error\">"), Err_end_ary = Bry_.new_a7("</strong>");
}

View File

@@ -24,7 +24,7 @@ public class Pfunc_ifeq extends Pf_func_base {
int self_args_len = self.Args_len(); if (self_args_len < 2) return; // no equal/not_equal clauses defined; return; EX: {{#if:a}} {{#if:a|b}}
byte[] lhs = Eval_argx(ctx, src, caller, self);
byte[] rhs = Pf_func_.Eval_arg_or_empty(ctx, src, caller, self, self_args_len, 0);
if (Pf_func_.Eq_(lhs, rhs))
if (Pf_func_.Eq(ctx, lhs, rhs))
bfr.Add(Pf_func_.Eval_arg_or_empty(ctx, src, caller, self, self_args_len, 1));
else
bfr.Add(Pf_func_.Eval_arg_or_empty(ctx, src, caller, self, self_args_len, 2));

View File

@@ -18,7 +18,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
package gplx.xowa.xtns.pfuncs.ifs; import gplx.*; import gplx.xowa.*; import gplx.xowa.xtns.*; import gplx.xowa.xtns.pfuncs.*;
import org.junit.*;
public class Pfunc_ifeq_tst {
private final Xop_fxt fxt = new Xop_fxt();
private final Xop_fxt fxt = new Xop_fxt();
@Before public void init() {fxt.Reset();}
@Test public void Ifeq_y() {fxt.Test_parse_tmpl_str_test("{{#ifeq:1|1|a|b}}" , "{{test}}" , "a");}

View File

@@ -16,30 +16,32 @@ You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package gplx.xowa.xtns.pfuncs.ifs; import gplx.*; import gplx.xowa.*; import gplx.xowa.xtns.*; import gplx.xowa.xtns.pfuncs.*;
import gplx.core.envs.*;
import gplx.core.envs.*; import gplx.core.caches.*;
import gplx.xowa.bldrs.wms.apis.*; import gplx.xowa.wikis.data.tbls.*;
import gplx.xowa.wikis.nss.*;
public class Pfunc_ifexist_mgr {
private Xowd_page_itm db_page = Xowd_page_itm.new_tmp();
private Hash_adp regy = Hash_adp_bry.cs();
public void Clear() {regy.Clear();}
private final Xowd_page_itm db_page = Xowd_page_itm.new_tmp();
public boolean Exists(Xowe_wiki wiki, byte[] raw_bry) {
if (Bry_.Len_eq_0(raw_bry)) return false; // return early; NOTE: {{autolink}} can pass in "" (see test)
Xoa_ttl ttl = Xoa_ttl.Parse(wiki, raw_bry); if (ttl == null) return false;
byte[] ttl_bry = ttl.Page_db(); // NOTE: must use Page_db; EX: {{#ifexist:File:Peter & Paul fortress in SPB 03.jpg|y|n}}
Object exists_obj = regy.Get_by(ttl_bry);
if (exists_obj != null) return ((Pfunc_ifexist_itm)exists_obj).Exists();
Pfunc_ifexist_itm exists_itm = new Pfunc_ifexist_itm(ttl_bry);
regy.Add(ttl_bry, exists_itm);
byte[] ttl_bry = ttl.Page_db(); // NOTE: must use Page_db; EX: {{#ifexist:File:Peter & Paul fortress in SPB 03.jpg|y|n}}
// try to get from cache
Gfo_cache_mgr cache_mgr = wiki.Cache_mgr().Ifexist_cache();
Pfunc_ifexist_itm cache_itm = (Pfunc_ifexist_itm)cache_mgr.Get_by_key(ttl_bry);
if (cache_itm != null) return cache_itm.Exists();
cache_itm = new Pfunc_ifexist_itm(ttl_bry);
cache_mgr.Add(ttl_bry, cache_itm, 1);
db_page.Clear();
Xow_ns ttl_ns = ttl.Ns();
boolean rv = false;
switch (ttl_ns.Id()) {
case Xow_ns_.Tid__special: rv = true; break; // NOTE: some pages call for [[Special]]; always return true for now; DATE:2014-07-17
case Xow_ns_.Tid__media: rv = Find_ttl_for_media_ns(exists_itm, wiki, ttl_ns, ttl_bry); break;
default: rv = Find_ttl_in_db(exists_itm, wiki, ttl_ns, ttl_bry); break;
case Xow_ns_.Tid__media: rv = Find_ttl_for_media_ns(cache_itm, wiki, ttl_ns, ttl_bry); break;
default: rv = Find_ttl_in_db(cache_itm, wiki, ttl_ns, ttl_bry); break;
}
exists_itm.Exists_(rv);
cache_itm.Exists_(rv);
return rv;
}
private boolean Find_ttl_in_db(Pfunc_ifexist_itm itm, Xowe_wiki wiki, Xow_ns ns, byte[] ttl_bry) {
@@ -73,8 +75,9 @@ public class Pfunc_ifexist_mgr {
}
}
}
class Pfunc_ifexist_itm {
class Pfunc_ifexist_itm implements Rls_able {
public Pfunc_ifexist_itm(byte[] ttl) {this.ttl = ttl;}
public byte[] Ttl() {return ttl;} private byte[] ttl;
public boolean Exists() {return exists;} public void Exists_(boolean v) {exists = v;} private boolean exists;
public void Rls() {}
}

View File

@@ -21,7 +21,7 @@ public class Pfunc_ifexist_tst {
private final Xop_fxt fxt = new Xop_fxt();
@Before public void init() {
fxt.Reset();
fxt.Wiki().Parser_mgr().Ifexist_mgr().Clear();
fxt.Wiki().Cache_mgr().Ifexist_cache().Clear();
}
@Test public void Basic_pass() {fxt.Test_parse_tmpl_str_test("{{#ifexist: Abc | exists | doesn't exist }}" , "{{test}}" , "doesn't exist");}
@Test public void Empty() {fxt.Test_parse_tmpl_str_test("{{#ifexist:|y|n}}" , "{{test}}" , "n");} // NOTE: {{autolink}} can pass in ""

View File

@@ -26,6 +26,7 @@ public class Pfunc_ifexpr extends Pf_func_base {
@Override public void Func_evaluate(Bry_bfr bfr, Xop_ctx ctx, Xot_invk caller, Xot_invk self, byte[] src) {
int self_args_len = self.Args_len();
byte[] argx = Eval_argx(ctx, src, caller, self); if (argx == null) return;
Pfunc_expr_shunter shunter = ctx.Tmp_mgr().Expr_shunter();
Decimal_adp result = shunter.Evaluate(ctx, argx);
boolean is_nan = result == Pfunc_expr_shunter.Null_rslt;
if (is_nan && shunter.Err().Len() > 0) {
@@ -39,5 +40,4 @@ public class Pfunc_ifexpr extends Pf_func_base {
bfr.Add(Pf_func_.Eval_arg_or_empty(ctx, src, caller, self, self_args_len, 0));
}
}
private final Pfunc_expr_shunter shunter = Pfunc_expr_shunter.Instance;
}

View File

@@ -38,7 +38,7 @@ public class Pfunc_switch extends Pf_func_base {
last_keyless_arg = null; // set last_keyless_arg to null
byte[] case_key = Get_or_eval(ctx, src, caller, self, bfr, arg.Key_tkn(), tmp);
if ( fall_thru_found // fall-thru found earlier; take cur value; EX: {{#switch:a|a|b=1|c=2}} -> 1
|| Pf_func_.Eq_(case_key, argx) // case_key matches argx; EX: {{#switch:a|a=1}}
|| Pf_func_.Eq(ctx, case_key, argx) // case_key matches argx; EX: {{#switch:a|a=1}}
) {
match = Get_or_eval(ctx, src, caller, self, bfr, arg.Val_tkn(), tmp);
break; // stop iterating; explicit match found;
@@ -52,7 +52,7 @@ public class Pfunc_switch extends Pf_func_base {
else { // = missing; EX: "|a|", "|#default|"
last_keyless_arg = arg;
byte[] case_val = Get_or_eval(ctx, src, caller, self, bfr, arg.Val_tkn(), tmp);
if (Pf_func_.Eq_(case_val, argx)) // argx matches case_val; EX: case_val="|a|" and argx="a"
if (Pf_func_.Eq(ctx, case_val, argx)) // argx matches case_val; EX: case_val="|a|" and argx="a"
fall_thru_found = true; // set as fall-thru; note that fall-thrus will have "val" in next keyed arg, so need to continue iterating; EX: {{#switch:a|a|b=1|c=2}} "a" is fall-thru, but "b" is next keyed arg with a val
else if (kwd_mgr.Kwd_default_match(case_val)) { // case_val starts with #default; EX: "|#default|" or "|#defaultabc|"
last_keyless_arg = null; // unflag last keyless arg else |#defaultabc| will be treated as last_keyless_arg and generate "#defaultabc"; DATE:2014-05-29

View File

@@ -23,11 +23,11 @@ public class Pfunc_plural extends Pf_func_base {
@Override public void Func_evaluate(Bry_bfr bfr, Xop_ctx ctx, Xot_invk caller, Xot_invk self, byte[] src) {// REF.MW: CoreParserFunctions.php
byte[] number = Eval_argx(ctx, src, caller, self);
int self_args_len = self.Args_len();
int arg_idx = Pf_func_.Eq_(number, Ary_Num_1) ? 0 : 1;
int arg_idx = Pf_func_.Eq(ctx, number, Ary_Num_1) ? 0 : 1;
if (arg_idx == 1 && self_args_len == 1) arg_idx = 0; // number is plural, but plural_arg not present; use singular; see test
byte[] word = Pf_func_.Eval_arg_or_empty(ctx, src, caller, self, self_args_len, arg_idx);
bfr.Add(word);
} static final byte[] Ary_Num_1 = new byte[] {Byte_ascii.Num_1};
} static final byte[] Ary_Num_1 = new byte[] {Byte_ascii.Num_1};
@Override public int Id() {return Xol_kwd_grp_.Id_i18n_plural;}
@Override public Pf_func New(int id, byte[] name) {return new Pfunc_plural().Name_(name);}
}

View File

@@ -23,6 +23,7 @@ public class Pfunc_scrib_lib implements Scrib_lib {
public Scrib_lua_mod Mod() {return mod;} private Scrib_lua_mod mod;
public Scrib_lib Init() {procs.Init_by_lib(this, Proc_names); return this;}
public void Core_(Scrib_core v) {this.core = v;} // TEST:
public Scrib_lib Clone_lib(Scrib_core core) {return new Pfunc_scrib_lib();}
public Scrib_lua_mod Register(Scrib_core core, Io_url script_dir) {
this.core = core;
Init();

View File

@@ -30,7 +30,7 @@ public class Pfunc_case extends Pf_func_base { // EX: {{lc:A}} -> a
Xol_lang_itm lang = ctx.Wiki().Lang();
boolean upper = case_type == Xol_lang_itm.Tid_upper;
if (first) {
Bry_bfr tmp_bfr = ctx.App().Utl__bfr_mkr().Get_b512();
Bry_bfr tmp_bfr = ctx.Wiki().Utl__bfr_mkr().Get_b512();
argx = lang.Case_mgr().Case_build_1st(tmp_bfr, upper, argx, 0, argx_len);
tmp_bfr.Mkr_rls();
}

View File

@@ -24,7 +24,7 @@ public class Pfunc_tag extends Pf_func_base {
@Override public boolean Func_require_colon_arg() {return true;}
@Override public void Func_evaluate(Bry_bfr bfr, Xop_ctx ctx, Xot_invk caller, Xot_invk self, byte[] src) {
// make <xnde> based on {{#tag}}; EX: {{#tag:ref|a|name=1}} -> <ref name='1'>a</ref>
Bry_bfr tmp_bfr = ctx.App().Utl__bfr_mkr().Get_b512();
Bry_bfr tmp_bfr = ctx.Wiki().Utl__bfr_mkr().Get_b512();
try {
// get tag_idx, tag_data, and tag_is_ref
int tag_idx = -1;

View File

@@ -163,56 +163,56 @@ public class Pft_fmt_itm_ {
.Add("xmY" , Pft_fmt_itm_.Hijiri_year_idx)
// TODO_OLD: space; "
;
public static Pft_fmt_itm[] Parse(Xop_ctx ctx, byte[] fmt) {
synchronized (fmt_itms) { // LOCK:static-obj; DATE:2016-07-06
Btrie_fast_mgr trie = Pft_fmt_itm_.Regy;
Btrie_rv trv = new Btrie_rv();
int i = 0, fmt_len = fmt.length;
fmt_itms.Clear(); int raw_bgn = String_.Pos_neg1; byte raw_byt = Byte_.Zero;
while (i < fmt_len) {
byte b = fmt[i];
Object o = trie.Match_at_w_b0(trv, b, fmt, i, fmt_len);
if (o != null) {
if (raw_bgn != String_.Pos_neg1) {fmt_itms.Add(i - raw_bgn == 1 ? new Pft_fmt_itm_raw_byt(raw_byt) : (Pft_fmt_itm)new Pft_fmt_itm_raw_ary(fmt, raw_bgn, i)); raw_bgn = String_.Pos_neg1;}
fmt_itms.Add((Pft_fmt_itm)o);
i = trv.Pos();
}
else {
switch (b) {
case Byte_ascii.Backslash:
if (raw_bgn != String_.Pos_neg1) {fmt_itms.Add(i - raw_bgn == 1 ? new Pft_fmt_itm_raw_byt(raw_byt) : (Pft_fmt_itm)new Pft_fmt_itm_raw_ary(fmt, raw_bgn, i)); raw_bgn = String_.Pos_neg1;}
++i; // peek next char
if (i == fmt_len) // trailing backslash; add one; EX: "b\" -> "b\" not "b"
fmt_itms.Add(new Pft_fmt_itm_raw_byt(Byte_ascii.Backslash));
else
fmt_itms.Add(new Pft_fmt_itm_raw_byt(fmt[i]));
++i;
break;
case Byte_ascii.Quote:
if (raw_bgn != String_.Pos_neg1) {fmt_itms.Add(i - raw_bgn == 1 ? new Pft_fmt_itm_raw_byt(raw_byt) : (Pft_fmt_itm)new Pft_fmt_itm_raw_ary(fmt, raw_bgn, i)); raw_bgn = String_.Pos_neg1;}
++i; // skip quote_bgn
raw_bgn = i;
while (i < fmt_len) {
b = fmt[i];
if (b == Byte_ascii.Quote) {
break;
}
else
++i;
List_adp fmt_itms = ctx.Wiki().Parser_mgr().Time_parser_itms();
Btrie_fast_mgr trie = Pft_fmt_itm_.Regy;
Btrie_rv trv = new Btrie_rv();
int i = 0, fmt_len = fmt.length;
fmt_itms.Clear(); int raw_bgn = String_.Pos_neg1; byte raw_byt = Byte_.Zero;
while (i < fmt_len) {
byte b = fmt[i];
Object o = trie.Match_at_w_b0(trv, b, fmt, i, fmt_len);
if (o != null) {
if (raw_bgn != String_.Pos_neg1) {fmt_itms.Add(i - raw_bgn == 1 ? new Pft_fmt_itm_raw_byt(raw_byt) : (Pft_fmt_itm)new Pft_fmt_itm_raw_ary(fmt, raw_bgn, i)); raw_bgn = String_.Pos_neg1;}
fmt_itms.Add((Pft_fmt_itm)o);
i = trv.Pos();
}
else {
switch (b) {
case Byte_ascii.Backslash:
if (raw_bgn != String_.Pos_neg1) {fmt_itms.Add(i - raw_bgn == 1 ? new Pft_fmt_itm_raw_byt(raw_byt) : (Pft_fmt_itm)new Pft_fmt_itm_raw_ary(fmt, raw_bgn, i)); raw_bgn = String_.Pos_neg1;}
++i; // peek next char
if (i == fmt_len) // trailing backslash; add one; EX: "b\" -> "b\" not "b"
fmt_itms.Add(new Pft_fmt_itm_raw_byt(Byte_ascii.Backslash));
else
fmt_itms.Add(new Pft_fmt_itm_raw_byt(fmt[i]));
++i;
break;
case Byte_ascii.Quote:
if (raw_bgn != String_.Pos_neg1) {fmt_itms.Add(i - raw_bgn == 1 ? new Pft_fmt_itm_raw_byt(raw_byt) : (Pft_fmt_itm)new Pft_fmt_itm_raw_ary(fmt, raw_bgn, i)); raw_bgn = String_.Pos_neg1;}
++i; // skip quote_bgn
raw_bgn = i;
while (i < fmt_len) {
b = fmt[i];
if (b == Byte_ascii.Quote) {
break;
}
fmt_itms.Add(i - raw_bgn == 0 ? new Pft_fmt_itm_raw_byt(Byte_ascii.Quote) : (Pft_fmt_itm)new Pft_fmt_itm_raw_ary(fmt, raw_bgn, i));
raw_bgn = String_.Pos_neg1;
++i; // skip quote_end
break;
default:
if (raw_bgn == String_.Pos_neg1) {raw_bgn = i; raw_byt = b;}
i += gplx.core.intls.Utf8_.Len_of_char_by_1st_byte(b);
break;
}
else
++i;
}
fmt_itms.Add(i - raw_bgn == 0 ? new Pft_fmt_itm_raw_byt(Byte_ascii.Quote) : (Pft_fmt_itm)new Pft_fmt_itm_raw_ary(fmt, raw_bgn, i));
raw_bgn = String_.Pos_neg1;
++i; // skip quote_end
break;
default:
if (raw_bgn == String_.Pos_neg1) {raw_bgn = i; raw_byt = b;}
i += gplx.core.intls.Utf8_.Len_of_char_by_1st_byte(b);
break;
}
}
if (raw_bgn != String_.Pos_neg1) {fmt_itms.Add(fmt_len - raw_bgn == 1 ? new Pft_fmt_itm_raw_byt(fmt[fmt_len - 1]) : (Pft_fmt_itm)new Pft_fmt_itm_raw_ary(fmt, raw_bgn, fmt_len)); raw_bgn = String_.Pos_neg1;}
return (Pft_fmt_itm[])fmt_itms.To_ary(Pft_fmt_itm.class);
}
} private static List_adp fmt_itms = List_adp_.New();
if (raw_bgn != String_.Pos_neg1) {fmt_itms.Add(fmt_len - raw_bgn == 1 ? new Pft_fmt_itm_raw_byt(fmt[fmt_len - 1]) : (Pft_fmt_itm)new Pft_fmt_itm_raw_ary(fmt, raw_bgn, fmt_len)); raw_bgn = String_.Pos_neg1;}
return (Pft_fmt_itm[])fmt_itms.To_ary(Pft_fmt_itm.class);
}
}

View File

@@ -17,7 +17,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package gplx.xowa.xtns.pfuncs.times; import gplx.*; import gplx.xowa.*; import gplx.xowa.xtns.*; import gplx.xowa.xtns.pfuncs.*;
import gplx.xowa.langs.*; import gplx.xowa.langs.kwds.*;
import gplx.xowa.parsers.*; import gplx.xowa.parsers.tmpls.*;
import gplx.xowa.parsers.*; import gplx.xowa.parsers.tmpls.*; import gplx.xowa.xtns.pfuncs.times.*;
public class Pft_func_date_int extends Pf_func_base {
public Pft_func_date_int(int id, int date_tid) {this.id = id; this.date_tid = date_tid;} private int date_tid;
@Override public int Id() {return id;} private int id;
@@ -25,6 +25,7 @@ public class Pft_func_date_int extends Pf_func_base {
@Override public void Func_evaluate(Bry_bfr bfr, Xop_ctx ctx, Xot_invk caller, Xot_invk self, byte[] src) {
DateAdp date = DateAdp_.MinValue;
Xowe_wiki wiki = ctx.Wiki(); Xol_lang_itm lang = ctx.Lang();
Pft_func_formatdate_bldr date_fmt_bldr = wiki.Parser_mgr().Date_fmt_bldr();
switch (date_tid) {
case Date_tid_lcl: date = DateAdp_.Now(); break;
case Date_tid_utc: date = DateAdp_.Now().XtoUtc(); break;
@@ -35,39 +36,39 @@ public class Pft_func_date_int extends Pf_func_base {
case Xol_kwd_grp_.Id_utc_year:
case Xol_kwd_grp_.Id_lcl_year:
case Xol_kwd_grp_.Id_rev_year:
Pft_func_formatdate.Date_bldr().Format(bfr, wiki, lang, date, Pft_fmt_itm_.Year_len4);
date_fmt_bldr.Format(bfr, wiki, lang, date, Pft_fmt_itm_.Year_len4);
break;
case Xol_kwd_grp_.Id_utc_month_int_len2:
case Xol_kwd_grp_.Id_lcl_month_int_len2:
case Xol_kwd_grp_.Id_rev_month_int_len2:
Pft_func_formatdate.Date_bldr().Format(bfr, wiki, lang, date, Pft_fmt_itm_.Month_int_len2);
date_fmt_bldr.Format(bfr, wiki, lang, date, Pft_fmt_itm_.Month_int_len2);
break;
case Xol_kwd_grp_.Id_utc_month_int:
case Xol_kwd_grp_.Id_lcl_month_int:
case Xol_kwd_grp_.Id_rev_month_int:
Pft_func_formatdate.Date_bldr().Format(bfr, wiki, lang, date, Pft_fmt_itm_.Month_int);
date_fmt_bldr.Format(bfr, wiki, lang, date, Pft_fmt_itm_.Month_int);
break;
case Xol_kwd_grp_.Id_utc_day_int_len2:
case Xol_kwd_grp_.Id_lcl_day_int_len2:
case Xol_kwd_grp_.Id_rev_day_int_len2:
Pft_func_formatdate.Date_bldr().Format(bfr, wiki, lang, date, Pft_fmt_itm_.Day_int_len2);
date_fmt_bldr.Format(bfr, wiki, lang, date, Pft_fmt_itm_.Day_int_len2);
break;
case Xol_kwd_grp_.Id_utc_day_int:
case Xol_kwd_grp_.Id_lcl_day_int:
case Xol_kwd_grp_.Id_rev_day_int:
Pft_func_formatdate.Date_bldr().Format(bfr, wiki, lang, date, Pft_fmt_itm_.Day_int);
date_fmt_bldr.Format(bfr, wiki, lang, date, Pft_fmt_itm_.Day_int);
break;
case Xol_kwd_grp_.Id_lcl_hour:
case Xol_kwd_grp_.Id_utc_hour:
Pft_func_formatdate.Date_bldr().Format(bfr, wiki, lang, date, Pft_fmt_itm_.Hour_base24_len2);
date_fmt_bldr.Format(bfr, wiki, lang, date, Pft_fmt_itm_.Hour_base24_len2);
break;
case Xol_kwd_grp_.Id_lcl_dow:
case Xol_kwd_grp_.Id_utc_dow:
Pft_func_formatdate.Date_bldr().Format(bfr, wiki, lang, date, Pft_fmt_itm_.Dow_base1_int);
date_fmt_bldr.Format(bfr, wiki, lang, date, Pft_fmt_itm_.Dow_base1_int);
break;
case Xol_kwd_grp_.Id_lcl_week:
case Xol_kwd_grp_.Id_utc_week:
Pft_func_formatdate.Date_bldr().Format(bfr, wiki, lang, date, Pft_fmt_itm_.WeekOfYear_int);
date_fmt_bldr.Format(bfr, wiki, lang, date, Pft_fmt_itm_.WeekOfYear_int);
break;
case Xol_kwd_grp_.Id_lcl_time:
case Xol_kwd_grp_.Id_utc_time: // 17:29

View File

@@ -35,13 +35,12 @@ public class Pft_func_formatdate extends Pf_func_base {
bfr.Add(date_bry);
return;
}
DateAdp date = Pft_func_time.ParseDate(date_bry, false, ctx.App().Utl__bfr_mkr().Get_b512().Mkr_rls());
DateAdp date = Pft_func_time.ParseDate(date_bry, false, ctx.Wiki().Utl__bfr_mkr().Get_b512().Mkr_rls());
if (date == null) {bfr.Add(date_bry); return;} // date not parseable; return self; DATE:2014-04-13
date_bldr.Format(bfr, ctx.Wiki(), ctx.Lang(), date, (Pft_fmt_itm[])o);
ctx.Wiki().Parser_mgr().Date_fmt_bldr().Format(bfr, ctx.Wiki(), ctx.Lang(), date, (Pft_fmt_itm[])o);
}
public static Pft_func_formatdate_bldr Date_bldr() {return date_bldr;} private static Pft_func_formatdate_bldr date_bldr = new Pft_func_formatdate_bldr();
private static final Pft_fmt_itm[] Fmt_itms_default = new Pft_fmt_itm[0];
private static final Btrie_fast_mgr trie = Btrie_fast_mgr.cs()
private static final Pft_fmt_itm[] Fmt_itms_default = new Pft_fmt_itm[0];
private static final Btrie_fast_mgr trie = Btrie_fast_mgr.cs()
.Add("dmy" , new Pft_fmt_itm[] {Pft_fmt_itm_.Day_int, Pft_fmt_itm_.Byte_space, Pft_fmt_itm_.Month_name, Pft_fmt_itm_.Byte_space, Pft_fmt_itm_.Year_len4})
.Add("mdy" , new Pft_fmt_itm[] {Pft_fmt_itm_.Month_name, Pft_fmt_itm_.Byte_space, Pft_fmt_itm_.Day_int, Pft_fmt_itm_.Byte_comma, Pft_fmt_itm_.Byte_space, Pft_fmt_itm_.Year_len4})
.Add("ymd" , new Pft_fmt_itm[] {Pft_fmt_itm_.Year_len4, Pft_fmt_itm_.Byte_space, Pft_fmt_itm_.Month_name, Pft_fmt_itm_.Byte_space, Pft_fmt_itm_.Day_int})

View File

@@ -22,46 +22,42 @@ public class Pft_func_formatdate_bldr {
public Pft_func_formatdate_bldr Idx_nxt_(int v) {idx_nxt = v; return this;} private int idx_nxt;
public Pft_fmt_itm[] Fmt_itms() {return fmt_itms;} private Pft_fmt_itm[] fmt_itms;
public void Format(Bry_bfr bfr, Xowe_wiki wiki, Xol_lang_itm lang, DateAdp date, Pft_fmt_itm fmt_itm) {
synchronized (this) { // LOCK:static-obj;Pft_func_formatdate.Date_bldr(); DATE:2016-07-07
fmt_itm.Fmt(bfr, wiki, lang, date, this);
}
fmt_itm.Fmt(bfr, wiki, lang, date, this);
}
public void Format(Bry_bfr bfr, Xowe_wiki wiki, Xol_lang_itm lang, DateAdp date, Pft_fmt_itm[] fmt_itms) {
synchronized (this) { // LOCK:static-obj;Pft_func_formatdate.Date_bldr(); DATE:2016-07-07
this.fmt_itms = fmt_itms;
int len = fmt_itms.length;
idx_cur = 0; idx_nxt = -1;
Pft_fmt_itm chained_fmt = null;
while (idx_cur < len) {
Pft_fmt_itm fmt_itm = fmt_itms[idx_cur];
if (fmt_itm.TypeId() == Pft_fmt_itm_.Tid_hebrew_numeral)
chained_fmt = fmt_itm;
else {
if (chained_fmt != null) {
Bry_bfr tmp_bfr = Xoa_app_.Utl__bfr_mkr().Get_b128();
synchronized (tmp_bfr) {
fmt_itm.Fmt(tmp_bfr, wiki, lang, date, this);
chained_fmt.Fmt(tmp_bfr, wiki, lang, date, this);
bfr.Add(tmp_bfr.To_bry_and_rls());
chained_fmt = null;
}
this.fmt_itms = fmt_itms;
int len = fmt_itms.length;
idx_cur = 0; idx_nxt = -1;
Pft_fmt_itm chained_fmt = null;
while (idx_cur < len) {
Pft_fmt_itm fmt_itm = fmt_itms[idx_cur];
if (fmt_itm.TypeId() == Pft_fmt_itm_.Tid_hebrew_numeral)
chained_fmt = fmt_itm;
else {
if (chained_fmt != null) {
Bry_bfr tmp_bfr = Xoa_app_.Utl__bfr_mkr().Get_b128();
synchronized (tmp_bfr) {
fmt_itm.Fmt(tmp_bfr, wiki, lang, date, this);
chained_fmt.Fmt(tmp_bfr, wiki, lang, date, this);
bfr.Add(tmp_bfr.To_bry_and_rls());
chained_fmt = null;
}
else
fmt_itm.Fmt(bfr, wiki, lang, date, this);
}
if (idx_nxt == -1)
++idx_cur;
else {
idx_cur = idx_nxt;
idx_nxt = -1;
}
else
fmt_itm.Fmt(bfr, wiki, lang, date, this);
}
if (chained_fmt != null) {
int year_int = bfr.To_int_and_clear(-1);
if (year_int != -1) { // handle no format; EX:{{#time:xh}} DATE:2014-07-20
date = DateAdp_.seg_(new int[] {year_int, date.Month(), date.Day(), date.Hour(), date.Minute(), date.Second(), date.Frac()});
chained_fmt.Fmt(bfr, wiki, lang, date, this);
}
if (idx_nxt == -1)
++idx_cur;
else {
idx_cur = idx_nxt;
idx_nxt = -1;
}
}
if (chained_fmt != null) {
int year_int = bfr.To_int_and_clear(-1);
if (year_int != -1) { // handle no format; EX:{{#time:xh}} DATE:2014-07-20
date = DateAdp_.seg_(new int[] {year_int, date.Month(), date.Day(), date.Hour(), date.Minute(), date.Second(), date.Frac()});
chained_fmt.Fmt(bfr, wiki, lang, date, this);
}
}
}

View File

@@ -30,6 +30,7 @@ public class Pft_func_time extends Pf_func_base {
byte[] arg_lang = Pf_func_.Eval_arg_or_empty(ctx, src, caller, self, self_args_len, 1);
Bry_bfr error_bfr = Bry_bfr_.New();
DateAdp date = ParseDate(arg_date, utc, error_bfr);
Xowe_wiki wiki = ctx.Wiki();
if (date == null || error_bfr.Len() > 0)
bfr.Add_str_a7("<strong class=\"error\">").Add_bfr_and_clear(error_bfr).Add_str_a7("</strong>");
else {
@@ -37,11 +38,11 @@ public class Pft_func_time extends Pf_func_base {
if (Bry_.Len_gt_0(arg_lang)) {
Xol_lang_stub specified_lang_itm = Xol_lang_stub_.Get_by_key_or_null(arg_lang);
if (specified_lang_itm != null) { // NOTE: if lang_code is bad, then ignore (EX:bad_code)
Xol_lang_itm specified_lang = ctx.Wiki().Appe().Lang_mgr().Get_by_or_new(arg_lang);
Xol_lang_itm specified_lang = wiki.Appe().Lang_mgr().Get_by_or_new(arg_lang);
lang = specified_lang;
}
}
Pft_func_formatdate.Date_bldr().Format(bfr, ctx.Wiki(), lang, date, fmt_ary);
wiki.Parser_mgr().Date_fmt_bldr().Format(bfr, wiki, lang, date, fmt_ary);
}
}
public static DateAdp ParseDate(byte[] date, boolean utc, Bry_bfr error_bfr) {

View File

@@ -45,10 +45,8 @@ class Pxd_parser {
fmtr.Bld_bfr(error_bfr, args);
} private Bry_bfr error_bfr = Bry_bfr_.New_w_size(32);
public DateAdp Parse(byte[] src, Bry_bfr error_bfr) {
// synchronized (this) { // LOCK:static-obj; DATE:2016-07-06
Tokenize(src); // NOTE: should check if Tokenize failed, but want to be liberal as date parser is not fully implemented; this will always default to 1st day of year; DATE:2014-03-27
return Evaluate(src, error_bfr);
// }
Tokenize(src); // NOTE: should check if Tokenize failed, but want to be liberal as date parser is not fully implemented; this will always default to 1st day of year; DATE:2014-03-27
return Evaluate(src, error_bfr);
}
private boolean Tokenize(byte[] src) {
this.src = src; src_len = src.length;

View File

@@ -35,7 +35,7 @@ public class Pfunc_anchorencode extends Pf_func_base { // EX: {{anchorencode:a b
@Override public void Func_evaluate(Bry_bfr bfr, Xop_ctx ctx, Xot_invk caller, Xot_invk self, byte[] src) {
if (anchor_ctx == null) Func_init(ctx);
byte[] val_ary = Eval_argx(ctx, src, caller, self); if (val_ary == Bry_.Empty) return;
Anchor_encode(val_ary, bfr, ctx.App().Utl__bfr_mkr().Get_b512().Mkr_rls());
Anchor_encode(val_ary, bfr, ctx.Wiki().Utl__bfr_mkr().Get_b512().Mkr_rls());
}
public static void Anchor_encode(byte[] src, Bry_bfr bfr, Bry_bfr tmp_bfr) {
Xop_root_tkn root = anchor_ctx.Tkn_mkr().Root(src);

View File

@@ -16,39 +16,40 @@ You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package gplx.xowa.xtns.pfuncs.ttls; import gplx.*; import gplx.xowa.*; import gplx.xowa.xtns.*; import gplx.xowa.xtns.pfuncs.*;
import gplx.core.envs.*;
import gplx.core.envs.*; import gplx.core.caches.*;
import gplx.xowa.langs.*; import gplx.xowa.langs.kwds.*;
import gplx.xowa.wikis.nss.*;
import gplx.xowa.files.*; import gplx.xowa.files.repos.*;
import gplx.xowa.files.origs.*;
import gplx.xowa.files.*; import gplx.xowa.files.repos.*; import gplx.xowa.files.origs.*;
import gplx.xowa.parsers.*; import gplx.xowa.parsers.tmpls.*;
public class Pfunc_filepath extends Pf_func_base {
@Override public boolean Func_require_colon_arg() {return true;}
@Override public int Id() {return Xol_kwd_grp_.Id_url_filepath;}
@Override public Pf_func New(int id, byte[] name) {return new Pfunc_filepath().Name_(name);}
@Override public void Func_evaluate(Bry_bfr bfr, Xop_ctx ctx, Xot_invk caller, Xot_invk self, byte[] src) {
// init
byte[] val_ary = Eval_argx(ctx, src, caller, self); if (val_ary == Bry_.Empty) return;
Xowe_wiki wiki = ctx.Wiki();
Xoa_ttl ttl = wiki.Ttl_parse(Xow_ns_.Tid__file, val_ary); if (ttl == null) return; // text is not valid ttl; exit;
Xoae_page page = Load_page(wiki, ttl); if (page.Db().Page().Exists_n()) return; // page not found in wiki or commons; exit;
byte[] ttl_bry = page.Ttl().Page_url();
// Xof_orig_itm orig_itm = wiki.File_mgr().Orig_mgr().Find_by_ttl_or_null(ttl_bry);
// if (orig_itm == Xof_orig_itm.Null) return;
// Xof_repo_itm repo = wiki.File_mgr().Repo_mgr().Get_trg_by_id_or_null(orig_itm.Repo()).Trg();
// url_bldr.Init_for_trg_html(Xof_repo_itm_.Mode_orig, repo, orig_itm.Ttl(), Xof_file_wkr_.Md5_fast(orig_itm.Ttl()), orig_itm.Ext(), -1, -1, -1);
// bfr.Add(url_bldr.Xto_bry());
Pfunc_filepath_itm commons_itm = Load_page(wiki, ttl); if (!commons_itm.Exists()) return; // page not found in wiki or commons; exit;
byte[] ttl_bry = commons_itm.Page_url();
// look for file
Xofw_file_finder_rslt tmp_rslt = wiki.File_mgr().Repo_mgr().Page_finder_locate(ttl_bry);
if (tmp_rslt.Repo_idx() == Byte_.Max_value_127) return;
Xof_repo_itm trg_repo = wiki.File_mgr().Repo_mgr().Repos_get_at(tmp_rslt.Repo_idx()).Trg();
Xof_xfer_itm xfer_itm = ctx.Tmp_mgr().Xfer_itm();
xfer_itm.Orig_ttl_and_redirect_(ttl_bry, Bry_.Empty); // redirect is empty b/c Get_page does all redirect lookups
byte[] url = url_bldr.Init_for_trg_html(Xof_repo_itm_.Mode_orig, trg_repo, ttl_bry, xfer_itm.Orig_ttl_md5(), xfer_itm.Orig_ext(), Xof_img_size.Size__neg1, Xof_lnki_time.Null, Xof_lnki_page.Null).Xto_bry();
byte[] url = wiki.Parser_mgr().Url_bldr().Init_for_trg_html(Xof_repo_itm_.Mode_orig, trg_repo, ttl_bry, xfer_itm.Orig_ttl_md5(), xfer_itm.Orig_ext(), Xof_img_size.Size__neg1, Xof_lnki_time.Null, Xof_lnki_page.Null).Xto_bry();
bfr.Add(url);
}
private static final Xof_xfer_itm xfer_itm = new Xof_xfer_itm();
private static final Xof_url_bldr url_bldr = new Xof_url_bldr();
private static Xoae_page Load_page(Xowe_wiki wiki, Xoa_ttl ttl) {
private static Pfunc_filepath_itm Load_page(Xowe_wiki wiki, Xoa_ttl ttl) {
// try to get from cache
Gfo_cache_mgr cache_mgr = wiki.Cache_mgr().Commons_cache();
byte[] cache_key = ttl.Page_url();
Pfunc_filepath_itm cache_itm = (Pfunc_filepath_itm)cache_mgr.Get_by_key(cache_key);
if (cache_itm != null) return cache_itm;
// do db retrieval
Xoae_page page = wiki.Data_mgr().Load_page_by_ttl(ttl);
if (page.Db().Page().Exists_n()) { // file not found in current wiki; try commons;
Xowe_wiki commons_wiki = (Xowe_wiki)wiki.Appe().Wiki_mgr().Get_by_or_null(wiki.Commons_wiki_key());
@@ -61,6 +62,16 @@ public class Pfunc_filepath extends Pf_func_base {
page = commons_wiki.Data_mgr().Load_page_by_ttl(ttl);
}
}
return page;
// add to cache
cache_itm = new Pfunc_filepath_itm(page.Db().Page().Exists(), cache_key);
cache_mgr.Add(cache_key, cache_itm, 1);
return cache_itm;
}
}
class Pfunc_filepath_itm implements Rls_able {
public Pfunc_filepath_itm(boolean exists, byte[] page_url) {this.exists = exists; this.page_url = page_url;}
public boolean Exists() {return exists;} private final boolean exists;
public byte[] Page_url() {return page_url;} private final byte[] page_url;
public void Rls() {}
}

View File

@@ -34,7 +34,7 @@ public class Pfunc_rel2abs extends Pf_func_base {
byte[] qry = Eval_argx(ctx, src, caller, self);
byte[] orig = Pf_func_.Eval_arg_or_empty(ctx, src, caller, self, self.Args_len(), 0);
if (orig.length == 0) orig = ctx.Page().Ttl().Full_txt_w_ttl_case();
bfr.Add(Rel2abs(ctx.App().Utl__bfr_mkr().Get_b512().Mkr_rls(), qry, orig));
bfr.Add(Rel2abs(ctx.Wiki().Utl__bfr_mkr().Get_b512().Mkr_rls(), qry, orig));
}
public static boolean Rel2abs_ttl(byte[] ttl, int bgn, int end) {
int last = end - 1;

View File

@@ -42,7 +42,7 @@ public class Pfunc_urlfunc extends Pf_func_base { // EX: {{lc:A}} -> a
.Add_mid(ttl_ary, xwiki.Key_bry().length + 1, ttl_ary.length); // "A#b?c=d"; +1 for colon after "commons:"; NOTE: ugly way of getting rest of url, but ttl currently does not have Full_wo_wiki
}
else {
Bry_bfr tmp_bfr = ctx.App().Utl__bfr_mkr().Get_b512().Mkr_rls();
Bry_bfr tmp_bfr = ctx.Wiki().Utl__bfr_mkr().Get_b512().Mkr_rls();
switch (tid) {
case Tid_local: tmp_bfr.Add(ctx.Wiki().Props().ArticlePath());break;
case Tid_full: tmp_bfr.Add(Bry_relative_url).Add(ctx.Wiki().Props().Server_name()).Add(ctx.Wiki().Props().ArticlePath()); break;