1
0
mirror of https://github.com/gnosygnu/xowa.git synced 2026-03-02 03:49:30 +00:00
This commit is contained in:
gnosygnu
2015-08-03 00:10:03 -04:00
parent 9d63f03b3d
commit 34c34f227c
514 changed files with 4972 additions and 3910 deletions

View File

@@ -23,14 +23,14 @@ 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) {
DecimalAdp rslt = shunter.Evaluate(ctx, expr); // NOTE: php uses "float" but really is a double; http://www.php.net/manual/en/language.types.float.php
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());
shunter.Err().Clear();
return false;
}
else {
bfr.Add_str(rslt.Xto_str());
bfr.Add_str(rslt.To_str());
return true;
}
}

View File

@@ -72,22 +72,22 @@ class Dot_tkn implements Expr_tkn {
class Val_stack {
public void Clear() {stack_len = 0;}
public int Len() {return stack_len;}
public DecimalAdp Pop() {
public Decimal_adp Pop() {
int stack_len_new = stack_len - 1;
DecimalAdp rv = stack[stack_len_new];
Decimal_adp rv = stack[stack_len_new];
stack_len = stack_len_new;
return rv;
}
public void Push(DecimalAdp v) {
public void Push(Decimal_adp v) {
int stack_len_new = stack_len + 1;
if (stack_len_new > stack_max) {
stack_max = stack_len_new * 2;
stack = (DecimalAdp[])Array_.Resize(stack, stack_max);
stack = (Decimal_adp[])Array_.Resize(stack, stack_max);
}
stack[stack_len] = v;
stack_len = stack_len_new;
}
DecimalAdp[] stack = new DecimalAdp[0]; int stack_len = 0, stack_max = 0;
Decimal_adp[] stack = new Decimal_adp[0]; int stack_len = 0, stack_max = 0;
}
class Func_tkn_stack {
public void Clear() {stack_len = 0;}
@@ -131,9 +131,9 @@ class Func_tkn_plus extends Func_tkn_base {
@Override public int Precedence() {return 6;}
@Override public Func_tkn GetAlt() {return Func_tkn_plus_positive._;}
@Override public boolean Calc_hook(Xop_ctx ctx, Pfunc_expr_shunter shunter, Val_stack val_stack) {
DecimalAdp rhs = val_stack.Pop();
DecimalAdp lhs = val_stack.Pop();
val_stack.Push(lhs.Op_add(rhs));
Decimal_adp rhs = val_stack.Pop();
Decimal_adp lhs = val_stack.Pop();
val_stack.Push(lhs.Add(rhs));
return true;
}
public static final Func_tkn_plus _ = new Func_tkn_plus(); Func_tkn_plus() {}
@@ -151,9 +151,9 @@ class Func_tkn_minus extends Func_tkn_base {
@Override public int Precedence() {return 6;}
@Override public Func_tkn GetAlt() {return Func_tkn_minus_negative._;}
@Override public boolean Calc_hook(Xop_ctx ctx, Pfunc_expr_shunter shunter, Val_stack val_stack) {
DecimalAdp rhs = val_stack.Pop();
DecimalAdp lhs = val_stack.Pop();
val_stack.Push(lhs.Op_subtract(rhs));
Decimal_adp rhs = val_stack.Pop();
Decimal_adp lhs = val_stack.Pop();
val_stack.Push(lhs.Subtract(rhs));
return true;
}
}
@@ -162,8 +162,8 @@ class Func_tkn_minus_negative extends Func_tkn_base {
@Override public int ArgCount() {return 1;}
@Override public int Precedence() {return 10;}
@Override public boolean Calc_hook(Xop_ctx ctx, Pfunc_expr_shunter shunter, Val_stack val_stack) {
DecimalAdp val = val_stack.Pop();
val_stack.Push(val.Op_mult(DecimalAdp_.Neg1));
Decimal_adp val = val_stack.Pop();
val_stack.Push(val.Multiply(Decimal_adp_.Neg1));
return true;
}
public static final Func_tkn_minus_negative _ = new Func_tkn_minus_negative("-");
@@ -173,13 +173,13 @@ class Func_tkn_divide extends Func_tkn_base {
@Override public int ArgCount() {return 2;}
@Override public int Precedence() {return 7;}
@Override public boolean Calc_hook(Xop_ctx ctx, Pfunc_expr_shunter shunter, Val_stack val_stack) {
DecimalAdp rhs = val_stack.Pop();
DecimalAdp lhs = val_stack.Pop();
Decimal_adp rhs = val_stack.Pop();
Decimal_adp lhs = val_stack.Pop();
if (rhs.Eq(0)) {
shunter.Err_set(ctx, Xol_msg_itm_.Id_pfunc_expr_division_by_zero);
return false;
}
val_stack.Push(lhs.Op_divide(rhs));
val_stack.Push(lhs.Divide(rhs));
return true;
}
}
@@ -188,9 +188,9 @@ class Func_tkn_times extends Func_tkn_base {
@Override public int ArgCount() {return 2;}
@Override public int Precedence() {return 7;}
@Override public boolean Calc_hook(Xop_ctx ctx, Pfunc_expr_shunter shunter, Val_stack val_stack) {
DecimalAdp rhs = val_stack.Pop();
DecimalAdp lhs = val_stack.Pop();
val_stack.Push(lhs.Op_mult(rhs));
Decimal_adp rhs = val_stack.Pop();
Decimal_adp lhs = val_stack.Pop();
val_stack.Push(lhs.Multiply(rhs));
return true;
}
}
@@ -199,19 +199,19 @@ class Func_tkn_pow extends Func_tkn_base {
@Override public int ArgCount() {return 2;}
@Override public int Precedence() {return 8;}
@Override public boolean Calc_hook(Xop_ctx ctx, Pfunc_expr_shunter shunter, Val_stack val_stack) {
DecimalAdp rhs = val_stack.Pop();
DecimalAdp lhs = val_stack.Pop();
int rhs_int = rhs.Xto_int();
if ((double)rhs_int == rhs.Xto_double()) // exponent is integer; use decimal pow which does less casts to double
val_stack.Push(lhs.Op_pow(rhs_int));
Decimal_adp rhs = val_stack.Pop();
Decimal_adp lhs = val_stack.Pop();
int rhs_int = rhs.To_int();
if ((double)rhs_int == rhs.To_double()) // exponent is integer; use decimal pow which does less casts to double
val_stack.Push(lhs.Pow(rhs_int));
else {
double rslt = Math_.Pow(lhs.Xto_double(), rhs.Xto_double());
double rslt = Math_.Pow(lhs.To_double(), rhs.To_double());
if (Double_.IsNaN(rslt)) {
shunter.Rslt_set(Double_.NaN_bry);
return false;
}
else
val_stack.Push(DecimalAdp_.double_thru_str_(rslt));
val_stack.Push(Decimal_adp_.double_thru_str_(rslt));
}
return true;
}
@@ -222,19 +222,19 @@ class Func_tkn_e_op extends Func_tkn_base {
@Override public int Precedence() {return 9;} // NOTE: needs to be < than - sign
@Override public Func_tkn GetAlt() {return Func_tkn_e_const._;}
@Override public boolean Calc_hook(Xop_ctx ctx, Pfunc_expr_shunter shunter, Val_stack val_stack) {
DecimalAdp rhs = val_stack.Pop();
DecimalAdp lhs = val_stack.Pop();
int rhs_int = rhs.Xto_int();
Decimal_adp rhs = val_stack.Pop();
Decimal_adp lhs = val_stack.Pop();
int rhs_int = rhs.To_int();
if ( rhs_int > 308
|| (lhs.Xto_double() >= 1.8f && rhs_int == 308)) { // PHP:"maximum of ~1.8e308"; verified with {{#expr:1.8e308}} on sandbox; REF:http://php.net/manual/en/language.types.float.php; PAGE:en.w:Factorial; en.w:Astatine; DATE:2015-04-08; DATE:2015-04-21
|| (lhs.To_double() >= 1.8f && rhs_int == 308)) { // PHP:"maximum of ~1.8e308"; verified with {{#expr:1.8e308}} on sandbox; REF:http://php.net/manual/en/language.types.float.php; PAGE:en.w:Factorial; en.w:Astatine; DATE:2015-04-08; DATE:2015-04-21
shunter.Rslt_set(Double_.Inf_pos_bry);
return false;
}
double rhs_double = rhs.Xto_double();
double rhs_double = rhs.To_double();
if ((double)rhs_int == rhs_double) // exponent is integer; use pow_10 which does less casts to double
val_stack.Push(lhs.Op_mult(DecimalAdp_.pow_10_(rhs_int)));
val_stack.Push(lhs.Multiply(Decimal_adp_.pow_10_(rhs_int)));
else
val_stack.Push(lhs.Op_mult(DecimalAdp_.double_thru_str_(Math_.Pow(10d, rhs_double))));
val_stack.Push(lhs.Multiply(Decimal_adp_.double_thru_str_(Math_.Pow(10d, rhs_double))));
return true;
}
}
@@ -245,13 +245,13 @@ class Func_tkn_mod extends Func_tkn_base {
@Override public boolean Calc_hook(Xop_ctx ctx, Pfunc_expr_shunter shunter, Val_stack val_stack) {
// must convert to int else issues with {{#expr:0.00999999mod10}} and {{USCensusPop|1960=763956|1970=756510}}; REF: http://php.net/manual/en/language.operators.arithmetic.php: "Operands of modulus are converted to integers (by stripping the decimal part) before processing"
// must convert to long else issues with (39052000900/1) mod 100 which should be 0, not 47; JAVA does not fail int conversion, and instead converts to Int_.MaxValue; EX: de.w:Quijano_(Pi<50>lagos)
long rhs = ((DecimalAdp)val_stack.Pop()).Xto_long();
long lhs = ((DecimalAdp)val_stack.Pop()).Xto_long();
long rhs = ((Decimal_adp)val_stack.Pop()).To_long();
long lhs = ((Decimal_adp)val_stack.Pop()).To_long();
if (rhs == 0) {
shunter.Err_set(ctx, Xol_msg_itm_.Id_pfunc_expr_division_by_zero);
return false;
}
val_stack.Push(DecimalAdp_.long_(lhs % rhs));
val_stack.Push(Decimal_adp_.long_(lhs % rhs));
return true;
}
}
@@ -260,9 +260,9 @@ class Func_tkn_eq extends Func_tkn_base {
@Override public int ArgCount() {return 2;}
@Override public int Precedence() {return 4;}
@Override public boolean Calc_hook(Xop_ctx ctx, Pfunc_expr_shunter shunter, Val_stack val_stack) {
DecimalAdp rhs = val_stack.Pop();
DecimalAdp lhs = val_stack.Pop();
val_stack.Push(lhs.Eq(rhs) ? DecimalAdp_.One : DecimalAdp_.Zero);
Decimal_adp rhs = val_stack.Pop();
Decimal_adp lhs = val_stack.Pop();
val_stack.Push(lhs.Eq(rhs) ? Decimal_adp_.One : Decimal_adp_.Zero);
return true;
}
}
@@ -271,9 +271,9 @@ class Func_tkn_neq extends Func_tkn_base {
@Override public int ArgCount() {return 2;}
@Override public int Precedence() {return 4;}
@Override public boolean Calc_hook(Xop_ctx ctx, Pfunc_expr_shunter shunter, Val_stack val_stack) {
DecimalAdp rhs = val_stack.Pop();
DecimalAdp lhs = val_stack.Pop();
val_stack.Push(lhs.Eq(rhs) ? DecimalAdp_.Zero : DecimalAdp_.One);
Decimal_adp rhs = val_stack.Pop();
Decimal_adp lhs = val_stack.Pop();
val_stack.Push(lhs.Eq(rhs) ? Decimal_adp_.Zero : Decimal_adp_.One);
return true;
}
}
@@ -282,9 +282,9 @@ class Func_tkn_gt extends Func_tkn_base {
@Override public int ArgCount() {return 2;}
@Override public int Precedence() {return 4;}
@Override public boolean Calc_hook(Xop_ctx ctx, Pfunc_expr_shunter shunter, Val_stack val_stack) {
DecimalAdp rhs = val_stack.Pop();
DecimalAdp lhs = val_stack.Pop();
val_stack.Push(lhs.Comp_gt(rhs) ? DecimalAdp_.One : DecimalAdp_.Zero);
Decimal_adp rhs = val_stack.Pop();
Decimal_adp lhs = val_stack.Pop();
val_stack.Push(lhs.Comp_gt(rhs) ? Decimal_adp_.One : Decimal_adp_.Zero);
return true;
}
}
@@ -293,9 +293,9 @@ class Func_tkn_lt extends Func_tkn_base {
@Override public int ArgCount() {return 2;}
@Override public int Precedence() {return 4;}
@Override public boolean Calc_hook(Xop_ctx ctx, Pfunc_expr_shunter shunter, Val_stack val_stack) {
DecimalAdp rhs = val_stack.Pop();
DecimalAdp lhs = val_stack.Pop();
val_stack.Push(lhs.Comp_lt(rhs) ? DecimalAdp_.One : DecimalAdp_.Zero);
Decimal_adp rhs = val_stack.Pop();
Decimal_adp lhs = val_stack.Pop();
val_stack.Push(lhs.Comp_lt(rhs) ? Decimal_adp_.One : Decimal_adp_.Zero);
return true;
}
}
@@ -304,9 +304,9 @@ class Func_tkn_gte extends Func_tkn_base {
@Override public int ArgCount() {return 2;}
@Override public int Precedence() {return 4;}
@Override public boolean Calc_hook(Xop_ctx ctx, Pfunc_expr_shunter shunter, Val_stack val_stack) {
DecimalAdp rhs = val_stack.Pop();
DecimalAdp lhs = val_stack.Pop();
val_stack.Push(lhs.Comp_gte(rhs) ? DecimalAdp_.One : DecimalAdp_.Zero);
Decimal_adp rhs = val_stack.Pop();
Decimal_adp lhs = val_stack.Pop();
val_stack.Push(lhs.Comp_gte(rhs) ? Decimal_adp_.One : Decimal_adp_.Zero);
return true;
}
}
@@ -315,9 +315,9 @@ class Func_tkn_lte extends Func_tkn_base {
@Override public int ArgCount() {return 2;}
@Override public int Precedence() {return 4;}
@Override public boolean Calc_hook(Xop_ctx ctx, Pfunc_expr_shunter shunter, Val_stack val_stack) {
DecimalAdp rhs = val_stack.Pop();
DecimalAdp lhs = val_stack.Pop();
val_stack.Push(lhs.Comp_lte(rhs) ? DecimalAdp_.One : DecimalAdp_.Zero);
Decimal_adp rhs = val_stack.Pop();
Decimal_adp lhs = val_stack.Pop();
val_stack.Push(lhs.Comp_lte(rhs) ? Decimal_adp_.One : Decimal_adp_.Zero);
return true;
}
}
@@ -326,9 +326,9 @@ class Func_tkn_and extends Func_tkn_base {
@Override public int ArgCount() {return 2;}
@Override public int Precedence() {return 3;}
@Override public boolean Calc_hook(Xop_ctx ctx, Pfunc_expr_shunter shunter, Val_stack val_stack) {
DecimalAdp rhs = val_stack.Pop();
DecimalAdp lhs = val_stack.Pop();
val_stack.Push(!lhs.Eq(0) && !rhs.Eq(0) ? DecimalAdp_.One : DecimalAdp_.Zero);
Decimal_adp rhs = val_stack.Pop();
Decimal_adp lhs = val_stack.Pop();
val_stack.Push(!lhs.Eq(0) && !rhs.Eq(0) ? Decimal_adp_.One : Decimal_adp_.Zero);
return true;
}
}
@@ -337,9 +337,9 @@ class Func_tkn_or extends Func_tkn_base {
@Override public int ArgCount() {return 2;}
@Override public int Precedence() {return 2;}
@Override public boolean Calc_hook(Xop_ctx ctx, Pfunc_expr_shunter shunter, Val_stack val_stack) {
DecimalAdp rhs = val_stack.Pop();
DecimalAdp lhs = val_stack.Pop();
val_stack.Push(!lhs.Eq(0) || !rhs.Eq(0) ? DecimalAdp_.One : DecimalAdp_.Zero);
Decimal_adp rhs = val_stack.Pop();
Decimal_adp lhs = val_stack.Pop();
val_stack.Push(!lhs.Eq(0) || !rhs.Eq(0) ? Decimal_adp_.One : Decimal_adp_.Zero);
return true;
}
}
@@ -348,8 +348,8 @@ class Func_tkn_not extends Func_tkn_base {
@Override public int ArgCount() {return 1;}
@Override public int Precedence() {return 9;}
@Override public boolean Calc_hook(Xop_ctx ctx, Pfunc_expr_shunter shunter, Val_stack val_stack) {
DecimalAdp val = val_stack.Pop();
val_stack.Push(val.Eq(0) ? DecimalAdp_.One : DecimalAdp_.Zero);
Decimal_adp val = val_stack.Pop();
val_stack.Push(val.Eq(0) ? Decimal_adp_.One : Decimal_adp_.Zero);
return true;
}
}
@@ -359,7 +359,7 @@ class Func_tkn_e_const extends Func_tkn_base {
@Override public int Precedence() {return 0;}
@Override public boolean Func_is_const() {return true;}
@Override public boolean Calc_hook(Xop_ctx ctx, Pfunc_expr_shunter shunter, Val_stack val_stack) {
val_stack.Push(DecimalAdp_.Const_e);
val_stack.Push(Decimal_adp_.Const_e);
return true;
}
public static final Func_tkn_e_const _ = new Func_tkn_e_const("e");
@@ -370,7 +370,7 @@ class Func_tkn_pi extends Func_tkn_base {
@Override public int Precedence() {return 0;}
@Override public boolean Func_is_const() {return true;}
@Override public boolean Calc_hook(Xop_ctx ctx, Pfunc_expr_shunter shunter, Val_stack val_stack) {
val_stack.Push(DecimalAdp_.Const_pi);
val_stack.Push(Decimal_adp_.Const_pi);
return true;
}
}
@@ -379,8 +379,8 @@ class Func_tkn_ceil extends Func_tkn_base {
@Override public int ArgCount() {return 1;}
@Override public int Precedence() {return 9;}
@Override public boolean Calc_hook(Xop_ctx ctx, Pfunc_expr_shunter shunter, Val_stack val_stack) {
DecimalAdp val = val_stack.Pop();
val_stack.Push(DecimalAdp_.double_(Math_.Ceil(val.Xto_double())));
Decimal_adp val = val_stack.Pop();
val_stack.Push(Decimal_adp_.double_(Math_.Ceil(val.To_double())));
return true;
}
}
@@ -389,8 +389,8 @@ class Func_tkn_trunc extends Func_tkn_base {
@Override public int ArgCount() {return 1;}
@Override public int Precedence() {return 9;}
@Override public boolean Calc_hook(Xop_ctx ctx, Pfunc_expr_shunter shunter, Val_stack val_stack) {
DecimalAdp val = val_stack.Pop();
val_stack.Push(DecimalAdp_.double_(Math_.Trunc(val.Xto_double())));
Decimal_adp val = val_stack.Pop();
val_stack.Push(Decimal_adp_.double_(Math_.Trunc(val.To_double())));
return true;
}
}
@@ -399,8 +399,8 @@ class Func_tkn_floor extends Func_tkn_base {
@Override public int ArgCount() {return 1;}
@Override public int Precedence() {return 9;}
@Override public boolean Calc_hook(Xop_ctx ctx, Pfunc_expr_shunter shunter, Val_stack val_stack) {
DecimalAdp val = val_stack.Pop();
val_stack.Push(DecimalAdp_.double_(Math_.Floor(val.Xto_double())));
Decimal_adp val = val_stack.Pop();
val_stack.Push(Decimal_adp_.double_(Math_.Floor(val.To_double())));
return true;
}
}
@@ -409,8 +409,8 @@ class Func_tkn_abs extends Func_tkn_base {
@Override public int ArgCount() {return 1;}
@Override public int Precedence() {return 9;}
@Override public boolean Calc_hook(Xop_ctx ctx, Pfunc_expr_shunter shunter, Val_stack val_stack) {
DecimalAdp val = val_stack.Pop();
val_stack.Push(val.Op_abs());
Decimal_adp val = val_stack.Pop();
val_stack.Push(val.Abs());
return true;
}
}
@@ -419,8 +419,8 @@ class Func_tkn_exp extends Func_tkn_base {
@Override public int ArgCount() {return 1;}
@Override public int Precedence() {return 9;}
@Override public boolean Calc_hook(Xop_ctx ctx, Pfunc_expr_shunter shunter, Val_stack val_stack) {
DecimalAdp val = val_stack.Pop();
val_stack.Push(DecimalAdp_.double_(Math_.Exp(val.Xto_double())));
Decimal_adp val = val_stack.Pop();
val_stack.Push(Decimal_adp_.double_(Math_.Exp(val.To_double())));
return true;
}
}
@@ -429,9 +429,9 @@ class Func_tkn_ln extends Func_tkn_base {
@Override public int ArgCount() {return 1;}
@Override public int Precedence() {return 9;}
@Override public boolean Calc_hook(Xop_ctx ctx, Pfunc_expr_shunter shunter, Val_stack val_stack) {
DecimalAdp val = val_stack.Pop();
Decimal_adp val = val_stack.Pop();
if (val.Comp_lte(0)) {shunter.Err_set(ctx, Xol_msg_itm_.Id_pfunc_expr_invalid_argument_ln); return false;}
val_stack.Push(DecimalAdp_.double_(Math_.Log(val.Xto_double())));
val_stack.Push(Decimal_adp_.double_(Math_.Log(val.To_double())));
return true;
}
}
@@ -440,8 +440,8 @@ class Func_tkn_sin extends Func_tkn_base {
@Override public int ArgCount() {return 1;}
@Override public int Precedence() {return 9;}
@Override public boolean Calc_hook(Xop_ctx ctx, Pfunc_expr_shunter shunter, Val_stack val_stack) {
DecimalAdp val = val_stack.Pop();
val_stack.Push(DecimalAdp_.double_(Math_.Sin(val.Xto_double())));
Decimal_adp val = val_stack.Pop();
val_stack.Push(Decimal_adp_.double_(Math_.Sin(val.To_double())));
return true;
}
}
@@ -450,8 +450,8 @@ class Func_tkn_cos extends Func_tkn_base {
@Override public int ArgCount() {return 1;}
@Override public int Precedence() {return 9;}
@Override public boolean Calc_hook(Xop_ctx ctx, Pfunc_expr_shunter shunter, Val_stack val_stack) {
DecimalAdp val = val_stack.Pop();
val_stack.Push(DecimalAdp_.double_(Math_.Cos(val.Xto_double())));
Decimal_adp val = val_stack.Pop();
val_stack.Push(Decimal_adp_.double_(Math_.Cos(val.To_double())));
return true;
}
}
@@ -460,8 +460,8 @@ class Func_tkn_tan extends Func_tkn_base {
@Override public int ArgCount() {return 1;}
@Override public int Precedence() {return 9;}
@Override public boolean Calc_hook(Xop_ctx ctx, Pfunc_expr_shunter shunter, Val_stack val_stack) {
DecimalAdp val = val_stack.Pop();
val_stack.Push(DecimalAdp_.double_(Math_.Tan(val.Xto_double())));
Decimal_adp val = val_stack.Pop();
val_stack.Push(Decimal_adp_.double_(Math_.Tan(val.To_double())));
return true;
}
}
@@ -470,9 +470,9 @@ class Func_tkn_asin extends Func_tkn_base {
@Override public int ArgCount() {return 1;}
@Override public int Precedence() {return 9;}
@Override public boolean Calc_hook(Xop_ctx ctx, Pfunc_expr_shunter shunter, Val_stack val_stack) {
DecimalAdp val = val_stack.Pop();
Decimal_adp val = val_stack.Pop();
if (val.Comp_lt(-1) || val.Comp_gt(1)) {shunter.Err_set(ctx, Xol_msg_itm_.Id_pfunc_expr_invalid_argument, this.Val_ary()); return false;}
val_stack.Push(DecimalAdp_.double_(Math_.Asin(val.Xto_double())));
val_stack.Push(Decimal_adp_.double_(Math_.Asin(val.To_double())));
return true;
}
}
@@ -481,9 +481,9 @@ class Func_tkn_acos extends Func_tkn_base {
@Override public int ArgCount() {return 1;}
@Override public int Precedence() {return 9;}
@Override public boolean Calc_hook(Xop_ctx ctx, Pfunc_expr_shunter shunter, Val_stack val_stack) {
DecimalAdp val = val_stack.Pop();
Decimal_adp val = val_stack.Pop();
if (val.Comp_lt(-1) || val.Comp_gt(1)) {shunter.Err_set(ctx, Xol_msg_itm_.Id_pfunc_expr_invalid_argument, this.Val_ary()); return false;}
val_stack.Push(DecimalAdp_.double_(Math_.Acos(val.Xto_double())));
val_stack.Push(Decimal_adp_.double_(Math_.Acos(val.To_double())));
return true;
}
}
@@ -492,8 +492,8 @@ class Func_tkn_atan extends Func_tkn_base {
@Override public int ArgCount() {return 1;}
@Override public int Precedence() {return 9;}
@Override public boolean Calc_hook(Xop_ctx ctx, Pfunc_expr_shunter shunter, Val_stack val_stack) {
DecimalAdp val = val_stack.Pop();
val_stack.Push(DecimalAdp_.double_(Math_.Atan(val.Xto_double())));
Decimal_adp val = val_stack.Pop();
val_stack.Push(Decimal_adp_.double_(Math_.Atan(val.To_double())));
return true;
}
}
@@ -502,17 +502,17 @@ class Func_tkn_round extends Func_tkn_base {
@Override public int ArgCount() {return 2;}
@Override public int Precedence() {return 5;}
@Override public boolean Calc_hook(Xop_ctx ctx, Pfunc_expr_shunter shunter, Val_stack val_stack) {
DecimalAdp rhs = val_stack.Pop();
DecimalAdp lhs = val_stack.Pop();
Decimal_adp rhs = val_stack.Pop();
Decimal_adp lhs = val_stack.Pop();
if (rhs.Comp_gt(16)) {
rhs = DecimalAdp_.int_(16);
rhs = Decimal_adp_.int_(16);
}
else if (rhs.Comp_lt(-16)) {
rhs = DecimalAdp_.int_(-16);
rhs = Decimal_adp_.int_(-16);
}
DecimalAdp val = lhs.Op_round(rhs.Xto_int());
if (val.Xto_double() == 0) // NOTE: must explicitly check for zero, else "0.0" will be pushed onto stack; EXE: {{#expr: 0 round 1}}; DATE:2013-11-09
val_stack.Push(DecimalAdp_.Zero);
Decimal_adp val = lhs.Round_old(rhs.To_int());
if (val.To_double() == 0) // NOTE: must explicitly check for zero, else "0.0" will be pushed onto stack; EXE: {{#expr: 0 round 1}}; DATE:2013-11-09
val_stack.Push(Decimal_adp_.Zero);
else
val_stack.Push(val);
return true;
@@ -523,13 +523,13 @@ class Func_tkn_fmod extends Func_tkn_base {
@Override public int ArgCount() {return 2;}
@Override public int Precedence() {return 7;}
@Override public boolean Calc_hook(Xop_ctx ctx, Pfunc_expr_shunter shunter, Val_stack val_stack) {
DecimalAdp rhs = (DecimalAdp)val_stack.Pop();
DecimalAdp lhs = (DecimalAdp)val_stack.Pop();
if (rhs.Xto_double() == 0) {
Decimal_adp rhs = (Decimal_adp)val_stack.Pop();
Decimal_adp lhs = (Decimal_adp)val_stack.Pop();
if (rhs.To_double() == 0) {
shunter.Err_set(ctx, Xol_msg_itm_.Id_pfunc_expr_division_by_zero);
return false;
}
val_stack.Push(lhs.Op_mod(rhs));
val_stack.Push(lhs.Mod(rhs));
return true;
}
}
@@ -538,8 +538,8 @@ class Func_tkn_sqrt extends Func_tkn_base {
@Override public int ArgCount() {return 1;}
@Override public int Precedence() {return 9;}
@Override public boolean Calc_hook(Xop_ctx ctx, Pfunc_expr_shunter shunter, Val_stack val_stack) {
DecimalAdp val = val_stack.Pop();
val_stack.Push(val.Op_sqrt());
Decimal_adp val = val_stack.Pop();
val_stack.Push(val.Sqrt());
return true;
}
}

View File

@@ -21,10 +21,10 @@ public class Pfunc_expr_shunter {
Btrie_fast_mgr trie = expression_();
Val_stack val_stack = new Val_stack();
Func_tkn_stack prc_stack = new Func_tkn_stack();
public static final DecimalAdp Null_rslt = null;
public static final Decimal_adp Null_rslt = null;
public Bry_bfr Err() {return err_bfr;} Bry_bfr err_bfr = Bry_bfr.new_();
public DecimalAdp Err_set(Xop_ctx ctx, int msgId) {return Err_set(ctx, msgId, Bry_.Empty);}
public DecimalAdp Err_set(Xop_ctx ctx, int msg_id, byte[] arg) {
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);
err_bfr.Clear().Add(Err_bgn_ary);
tmp_fmtr.Fmt_(msg_val).Bld_bfr_one(err_bfr, arg);
@@ -34,7 +34,7 @@ public class Pfunc_expr_shunter {
public void Rslt_set(byte[] bry) {
err_bfr.Add(bry);
}
public DecimalAdp Evaluate(Xop_ctx ctx, byte[] src) { // REF.MW: Expr.php
public Decimal_adp Evaluate(Xop_ctx ctx, byte[] src) { // REF.MW: Expr.php
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;
@@ -74,8 +74,8 @@ public class Pfunc_expr_shunter {
default: loop = false; break;
}
}
DecimalAdp num = Null_rslt;
try {num = Bry_.XtoDecimalByPos(src, numBgn, cur_pos);}
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);
@@ -86,7 +86,7 @@ public class Pfunc_expr_shunter {
case 0: dot_count = 1; break;
case 1:
try {
num = Bry_.XtoDecimalByPos(src, numBgn, i);
num = Bry_.To_decimal(src, numBgn, i);
}
catch (Exception exc_inner) {Err_.Noop(exc_inner);}
break;

View File

@@ -109,7 +109,7 @@ public class Pfunc_iferror extends Pf_func_base {
private static final Btrie_slim_mgr trie = trie_();
static final byte State_null = 0, State_nde = 1, State_class = 2, State_error = 3, State_close = 4;
private static Btrie_slim_mgr trie_() {
Btrie_slim_mgr rv = Btrie_slim_mgr.ci_ascii_(); // NOTE:ci.ascii:MW_const.en
Btrie_slim_mgr rv = Btrie_slim_mgr.ci_a7(); // NOTE:ci.ascii:MW_const.en
trie_init(rv, State_nde , "<strong");
trie_init(rv, State_nde , "<span");
trie_init(rv, State_nde , "<p");

View File

@@ -19,7 +19,7 @@ package gplx.xowa.xtns.pfuncs.ifs; import gplx.*; import gplx.xowa.*; import gpl
import gplx.xowa.wmfs.apis.*; import gplx.xowa.wikis.data.tbls.*;
public class Pfunc_ifexist_mgr {
private Xowd_page_itm db_page = Xowd_page_itm.new_tmp();
private Hash_adp regy = Hash_adp_bry.cs_();
private Hash_adp regy = Hash_adp_bry.cs();
public void Clear() {regy.Clear();}
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)

View File

@@ -23,14 +23,14 @@ public class Pfunc_ifexpr extends Pf_func_base {
int self_args_len = self.Args_len();
byte[] val_dat_ary = Eval_argx(ctx, src, caller, self);
if (val_dat_ary == null) return;
DecimalAdp result = shunter.Evaluate(ctx, val_dat_ary);
Decimal_adp result = shunter.Evaluate(ctx, val_dat_ary);
boolean is_nan = result == Pfunc_expr_shunter.Null_rslt;
if (is_nan && shunter.Err().Len() > 0) {
bb.Add_bfr_and_preserve(shunter.Err());
shunter.Err().Clear();
}
else {
if (is_nan || result.Xto_int() == 0)
if (is_nan || result.To_int() == 0)
bb.Add(Pf_func_.Eval_arg_or_empty(ctx, src, caller, self, self_args_len, 1));
else
bb.Add(Pf_func_.Eval_arg_or_empty(ctx, src, caller, self, self_args_len, 0));

View File

@@ -52,7 +52,7 @@ public class Pfunc_gender extends Pf_func_base {
Object o = gender_cache.Get_by_bry(user_name);
return o == null ? user.Gender() : ((Int_obj_val)o).Val();
}
private static final Hash_adp_bry gender_cache = Hash_adp_bry.cs_() // for tests
private static final Hash_adp_bry gender_cache = Hash_adp_bry.cs() // for tests
.Add_str_int("xowa_male" , Xol_gender_.Tid_male)
.Add_str_int("xowa_female" , Xol_gender_.Tid_female)
;

View File

@@ -42,11 +42,8 @@ public class Pfunc_scrib_lib implements Scrib_lib {
public boolean Expr(Scrib_proc_args args, Scrib_proc_rslt rslt) {
byte[] expr_bry = args.Pull_bry(0);
Bry_bfr tmp_bfr = core.Wiki().Utl__bfr_mkr().Get_b128();
boolean pass = Pfunc_expr.Evaluate(tmp_bfr, core.Ctx(), expr_bry);
Pfunc_expr.Evaluate(tmp_bfr, core.Ctx(), expr_bry);
String expr_rslt = tmp_bfr.To_str_and_rls();
if (pass)
return rslt.Init_obj(expr_rslt);
else
throw Err_.new_wo_type(expr_rslt);
return rslt.Init_obj(expr_rslt); // NOTE: always return rslt; don't throw error even if expr is invalid; EX:mw.ParserFuntion.expr('fail'); PAGE:es.w:Freer_(Texas) DATE:2015-07-28
}
}

View File

@@ -25,7 +25,10 @@ public class Pfunc_scrib_lib_tst {
lib.Init();
lib.Core_(fxt.Core());
} private Scrib_invoke_func_fxt fxt = new Scrib_invoke_func_fxt(); private Pfunc_scrib_lib lib;
@Test public void Expr() {
@Test public void Expr__pass() {
fxt.Test_scrib_proc_str(lib, Pfunc_scrib_lib.Invk_expr, Object_.Ary("1 + 2") , "3");
}
@Test public void Expr__fail() { // PURPOSE: if bad input don't throw error; return error message; PAGE:es.w:Freer_(Texas) DATE:2015-07-28
fxt.Test_scrib_proc_str(lib, Pfunc_scrib_lib.Invk_expr, Object_.Ary("fail") , "<strong class=\"error\">Expression error: Unrecognised word \"fail\"</strong>");
}
}

View File

@@ -26,15 +26,15 @@ public class Pfunc_case_tst {
@Test public void Uc() {fxt.Test_parse_tmpl_str_test("{{uc:abc}}" , "{{test}}", "ABC");}
@Test public void Uc_first() {fxt.Test_parse_tmpl_str_test("{{ucfirst:abc}}" , "{{test}}", "Abc");}
@Test public void Multi_byte() {// NOTE: separate test b/c will sometimes fail in suite
fxt.Wiki().Lang().Case_mgr_utf8_();
fxt.Wiki().Lang().Case_mgr_u8_();
fxt.Test_parse_tmpl_str_test("{{uc:ĉ}}" , "{{test}}", "Ĉ"); // upper all
}
@Test public void Multi_byte_asymmetric() {
fxt.Wiki().Lang().Case_mgr_utf8_();
fxt.Wiki().Lang().Case_mgr_u8_();
fxt.Test_parse_tmpl_str_test("{{uc:ⱥ}}" , "{{test}}", "Ⱥ"); // handle multi-byte asymmetry (lc is 3 bytes; uc is 2 bytes)
}
@Test public void Multi_byte_first() {
fxt.Wiki().Lang().Case_mgr_utf8_();
fxt.Wiki().Lang().Case_mgr_u8_();
fxt.Test_parse_tmpl_str_test("{{ucfirst:провинция}}" , "{{test}}", "Провинция"); // upper first; DATE:2014-02-04
}
}

View File

@@ -24,7 +24,7 @@ public class Pfunc_pad extends Pf_func_base {
int val_len = Utf8_.Len_of_bry(val); // NOTE: length must be in chars, not bytes, else won't work for non-ASCII chars; EX:niǎo has length of 4, not 5; PAGE:zh.d:不 DATE:2014-08-27
byte[] pad_len = Pf_func_.Eval_arg_or_empty(ctx, src, caller, self, self_args_len, 0);
int pad_len_int = Bry_.Xto_int_or(pad_len, 0, pad_len.length, -1);
int pad_len_int = Bry_.To_int_or(pad_len, 0, pad_len.length, -1);
if (pad_len_int == -1) {bfr.Add(val); return;} // NOTE: if pad_len is non-int, add val and exit silently; EX: {{padleft: a|bad|0}}
if (pad_len_int > 500) pad_len_int = 500; // MW: force it to be <= 500

View File

@@ -25,7 +25,7 @@ public class Pfunc_pad_tst {
@Test public void L_len_neg1() {fxt.Test_parse_tmpl_str_test("{{padleft: a|-1|01}}" , "{{test}}" , "a");}
@Test public void L_val_null() {fxt.Test_parse_tmpl_str_test("{{padleft: |4|0}}" , "{{test}}" , "0000");}
@Test public void L_word_3() {fxt.Test_parse_tmpl_str_test("{{padleft: abc|4}}" , "{{test}}" , "0abc");}
@Test public void L_word_3_utf8() {fxt.Test_parse_tmpl_str_test("{{padleft: niǎo|5}}" , "{{test}}" , "0niǎo");} // PURPOSE:use length of String in chars, not bytes; PAGE:zh.d:不 DATE:2014-08-27
@Test public void L_word_3_u8() {fxt.Test_parse_tmpl_str_test("{{padleft: niǎo|5}}" , "{{test}}" , "0niǎo");} // PURPOSE:use length of String in chars, not bytes; PAGE:zh.d:不 DATE:2014-08-27
@Test public void L_exc_len_bad1() {fxt.Test_parse_tmpl_str_test("{{padleft:a|bad|01}}" , "{{test}}" , "a");}
@Test public void L_exc_pad_ws() {fxt.Test_parse_tmpl_str_test("{{padleft:a|4|\n \t}}" , "{{test}}" , "a");}
@Test public void R_len_3() {fxt.Test_parse_tmpl_str_test("{{padright:a|4|0}}" , "{{test}}" , "a000");}

View File

@@ -30,10 +30,10 @@ public class Pfunc_explode extends Pf_func_base {
if (Bry_.Len_eq_0(dlm)) dlm = Byte_ascii.Space_bry; // handle empty String; EX: {{#explode:a b||1}}
if (args_len > 1) {
byte[] pos_bry = Pf_func_.Eval_arg_or(ctx, src, caller, self, args_len, 1, null);
if (pos_bry != null) idx = Bry_.Xto_int_or(pos_bry, 0);
if (pos_bry != null) idx = Bry_.To_int_or(pos_bry, 0);
if (args_len > 2) {
byte[] limit_bry = Pf_func_.Eval_arg_or(ctx, src, caller, self, args_len, 2, null);
if (limit_bry != null) limit = Bry_.Xto_int_or(pos_bry, -1);
if (limit_bry != null) limit = Bry_.To_int_or(pos_bry, -1);
}
}
}

View File

@@ -25,7 +25,7 @@ public class Pfunc_pos extends Pf_func_base {
int self_args_len = self.Args_len();
byte[] find = Pf_func_.Eval_arg_or(ctx, src, caller, self, self_args_len, 0, Byte_ascii.Space_bry); // MW: use " " if find is missing
byte[] offset_bry = Pf_func_.Eval_arg_or(ctx, src, caller, self, self_args_len, 1, null);
int offset = offset_bry == null ? 0 : Bry_.Xto_int(offset_bry);
int offset = offset_bry == null ? 0 : Bry_.To_int_or_neg1(offset_bry);
int pos = Bry_finder.Find_fwd(str, find, offset);
if (pos != Bry_finder.Not_found)
trg.Add_int_variable(pos);

View File

@@ -27,7 +27,7 @@ public class Pfunc_replace extends Pf_func_base {
if (Bry_.Len_eq_0(find)) find = Byte_ascii.Space_bry; // NOTE: MW defaults empty finds to space (" "); note that leaving it as "" would cause Replace to loop infinitely
byte[] repl = Pf_func_.Eval_arg_or(ctx, src, caller, self, self_args_len, 1, Bry_.Empty);
byte[] limit_bry = Pf_func_.Eval_arg_or(ctx, src, caller, self, self_args_len, 2, null);
int limit = limit_bry == null ? Int_.MaxValue : Bry_.Xto_int(limit_bry);
int limit = limit_bry == null ? Int_.MaxValue : Bry_.To_int_or_neg1(limit_bry);
Bry_bfr tmp_bfr = Xoa_app_.Utl__bfr_mkr().Get_b128();
byte[] rv = Bry_.Replace(tmp_bfr, str, find, repl, 0, str.length, limit);
tmp_bfr.Mkr_rls();

View File

@@ -25,7 +25,7 @@ public class Pfunc_rpos extends Pf_func_base {
int self_args_len = self.Args_len();
byte[] find = Pf_func_.Eval_arg_or(ctx, src, caller, self, self_args_len, 0, Byte_ascii.Space_bry); // MW: use " " if find is missing
byte[] offset_bry = Pf_func_.Eval_arg_or(ctx, src, caller, self, self_args_len, 1, null);
int offset = offset_bry == null ? str.length : Bry_.Xto_int(offset_bry);
int offset = offset_bry == null ? str.length : Bry_.To_int_or_neg1(offset_bry);
int pos = Bry_finder.Find_bwd(str, find, offset);
if (pos == Bry_finder.Not_found) pos = -1;
trg.Add_int_variable(pos);

View File

@@ -26,10 +26,10 @@ public class Pfunc_sub extends Pf_func_base {
int bgn = 0, len = Int_.MinValue;
if (self_args_len > 0) {
byte[] bgn_bry = Pf_func_.Eval_arg_or(ctx, src, caller, self, self_args_len, 0, null);
if (bgn_bry != null) bgn = Bry_.Xto_int_or(bgn_bry, 0);
if (bgn_bry != null) bgn = Bry_.To_int_or(bgn_bry, 0);
if (self_args_len > 1) {
byte[] len_bry = Pf_func_.Eval_arg_or(ctx, src, caller, self, self_args_len, 1, null);
if (len_bry != null) len = Bry_.Xto_int_or(len_bry, Int_.MinValue);
if (len_bry != null) len = Bry_.To_int_or(len_bry, Int_.MinValue);
}
}
int s_len = s.length;

View File

@@ -44,6 +44,14 @@ public class Pft_fmt_itm_ {
, Tid_hebrew_month_name_full = 23
, Tid_hebrew_month_name_gen = 24
, Tid_hebrew_numeral = 25
, Tid_iranian_year_idx = 26
, Tid_iranian_month_idx = 27
, Tid_iranian_day_idx = 28
, Tid_iranian_month_name = 29
, Tid_hijiri_year_idx = 30
, Tid_hijiri_month_idx = 31
, Tid_hijiri_day_idx = 32
, Tid_hijiri_month_name = 33
;
public static final Pft_fmt_itm
@@ -91,6 +99,14 @@ public class Pft_fmt_itm_ {
, Iso_fmt = new Pft_fmt_itm_iso_fmt()
, Rfc_5322 = new Pft_fmt_itm_rfc_5322()
, Timezone_offset = new Pft_fmt_itm_timezone_offset()
, Iranian_year_idx = new Pft_fmt_itm_iranian_year_idx()
, Iranian_month_idx = new Pft_fmt_itm_iranian_month_idx()
, Iranian_day_idx = new Pft_fmt_itm_iranian_day_idx()
, Iranian_month_name = new Pft_fmt_itm_iranian_month_name()
, Hijiri_year_idx = new Pft_fmt_itm_hijiri_year_idx()
, Hijiri_month_idx = new Pft_fmt_itm_hijiri_month_idx()
, Hijiri_day_idx = new Pft_fmt_itm_hijiri_day_idx()
, Hijiri_month_name = new Pft_fmt_itm_hijiri_month_name()
;
public static final Btrie_fast_mgr Regy = Btrie_fast_mgr.cs_()
.Add(Byte_ascii.Ltr_Y , Pft_fmt_itm_.Year_len4) // 2012
@@ -135,7 +151,15 @@ public class Pft_fmt_itm_ {
.Add("xjx" , Pft_fmt_itm_.Hebrew_month_name_gen)
.Add("xjY" , Pft_fmt_itm_.Hebrew_year_num)
.Add("xh" , Pft_fmt_itm_.Hebrew_numeral)
// TODO: foreign; space; "
.Add("xij" , Pft_fmt_itm_.Iranian_day_idx)
.Add("xiF" , Pft_fmt_itm_.Iranian_month_name)
.Add("xin" , Pft_fmt_itm_.Iranian_month_idx)
.Add("xiY" , Pft_fmt_itm_.Iranian_year_idx)
.Add("xmj" , Pft_fmt_itm_.Hijiri_day_idx)
.Add("xmF" , Pft_fmt_itm_.Hijiri_month_name)
.Add("xmn" , Pft_fmt_itm_.Hijiri_month_idx)
.Add("xmY" , Pft_fmt_itm_.Hijiri_year_idx)
// TODO: space; "
;
public static Pft_fmt_itm[] Parse(Xop_ctx ctx, byte[] fmt) {
Btrie_fast_mgr trie = Pft_fmt_itm_.Regy;

View File

@@ -92,243 +92,57 @@ class Pft_fmt_itm_hebrew_numeral implements Pft_fmt_itm {
bfr.Add_str(Pft_fmt_itm_hebrew_.Calc_hebrew_numeral(date.Year()));
}
}
class Pft_fmt_itm_hebrew_ {
public static int Calc_hebrew_year_num_start(int year) {
int year_minus_1 = year - 1;
int a = (12 * year_minus_1 + 17) % 19;
int b = year_minus_1 % 4;
double m = 32.044093161144d + 1.5542417966212d * a + b / 4.0 - 0.0031777940220923d * year_minus_1;
if (m < 0)
m--;
int mar = (int)m;
if (m < 0)
m++;
m -= mar;
int c = (mar + 3 * year_minus_1 + 5 * b + 5) % 7;
if (c == 0 && a > 11 && m >= 0.89772376543210d)
mar++;
else if (c == 1 && a > 6 && m >= 0.63287037037037d)
mar += 2;
else if (c == 2 || c == 4 || c == 6)
mar++;
double year_minus_3761 = year - 3761;
mar += (int)(year_minus_3761 / 100 ) - (int)(year_minus_3761 / 400) - 24;
return mar;
}
private static final int[] Hebrew_date_rslt = new int[4];
public static int[] Calc_hebrew_date(DateAdp date) {
synchronized (Hebrew_date_rslt) {
Calc_hebrew_date(Hebrew_date_rslt, date.Year(), date.Month(), date.Day());
return Hebrew_date_rslt;
}
}
public static boolean Calc_hebrew_date(int[] rv, int year, int month, int day) { // REF.MW:Language.php|tsToHebrew
// Calculate Hebrew year
int hebrewYear = year + 3760;
// Month number when September = 1, August = 12
month += 4;
if (month > 12) {
// Next year
month -= 12;
year++;
hebrewYear++;
}
// Calculate day of year from 1 September
int dayOfYear = day;
for (int i = 1; i < month; i++) {
if (i == 6) {
// February
dayOfYear += 28;
// Check if the year is leap
if (year % 400 == 0 || (year % 4 == 0 && year % 100 > 0)) {
dayOfYear++;
}
} else if (i == 8 || i == 10 || i == 1 || i == 3) {
dayOfYear += 30;
} else {
dayOfYear += 31;
}
}
// Calculate the start of the Hebrew year
int start = Calc_hebrew_year_num_start(hebrewYear);
// Calculate next year's start
int nextStart = 0;
if (dayOfYear <= start) {
// Day is before the start of the year - it is the previous year
// Next year's start
nextStart = start;
// Previous year
year--;
hebrewYear--;
// Add days since previous year's 1 September
dayOfYear += 365;
if ((year % 400 == 0) || (year % 100 != 0 && year % 4 == 0)) {
// Leap year
dayOfYear++;
}
// Start of the new (previous) year
start = Calc_hebrew_year_num_start(hebrewYear);
} else {
// Next year's start
nextStart = Calc_hebrew_year_num_start(hebrewYear + 1);
}
// Calculate Hebrew day of year
int hebrewDayOfYear = dayOfYear - start;
// Difference between year's days
int diff = nextStart - start;
// Add 12 (or 13 for leap years) days to ignore the difference between
// Hebrew and Gregorian year (353 at least vs. 365/6) - now the
// difference is only about the year type
if ((year % 400 == 0) || (year % 100 != 0 && year % 4 == 0)) {
diff += 13;
} else {
diff += 12;
}
// Check the year pattern, and is leap year
// 0 means an incomplete year, 1 means a regular year, 2 means a complete year
// This is mod 30, to work on both leap years (which add 30 days of Adar I)
// and non-leap years
int yearPattern = diff % 30;
// Check if leap year
boolean isLeap = diff >= 30;
// Calculate day in the month from number of day in the Hebrew year
// Don't check Adar - if the day is not in Adar, we will stop before;
// if it is in Adar, we will use it to check if it is Adar I or Adar II
int hebrewDay = hebrewDayOfYear;
int hebrewMonth = 1;
int days = 0;
while (hebrewMonth <= 12) {
// Calculate days in this month
if (isLeap && hebrewMonth == 6) {
// Adar in a leap year
if (isLeap) {
// Leap year - has Adar I, with 30 days, and Adar II, with 29 days
days = 30;
if (hebrewDay <= days) {
// Day in Adar I
hebrewMonth = 13;
} else {
// Subtract the days of Adar I
hebrewDay -= days;
// Try Adar II
days = 29;
if (hebrewDay <= days) {
// Day in Adar II
hebrewMonth = 14;
}
}
}
} else if (hebrewMonth == 2 && yearPattern == 2) {
// Cheshvan in a complete year (otherwise as the rule below)
days = 30;
} else if (hebrewMonth == 3 && yearPattern == 0) {
// Kislev in an incomplete year (otherwise as the rule below)
days = 29;
} else {
// Odd months have 30 days, even have 29
days = 30 - (hebrewMonth - 1) % 2;
}
if (hebrewDay <= days) {
// In the current month
break;
} else {
// Subtract the days of the current month
hebrewDay -= days;
// Try in the next month
hebrewMonth++;
}
}
rv[0] = hebrewYear;
rv[1] = hebrewMonth;
rv[2] = hebrewDay;
rv[3] = days;
return true;
}
public static byte[] Get_hebrew_month_name_full(Xowe_wiki wiki, DateAdp date) {return Get_hebrew_month_name(wiki, date, Month_name_full_ary);}
public static byte[] Get_hebrew_month_name_gen(Xowe_wiki wiki, DateAdp date) {return Get_hebrew_month_name(wiki, date, Month_name_gen_ary);}
private static byte[] Get_hebrew_month_name(Xowe_wiki wiki, DateAdp date, byte[][] name_ary) {
int[] hebrew_date = Pft_fmt_itm_hebrew_.Calc_hebrew_date(date);
int hebrew_month = hebrew_date[Pft_fmt_itm_hebrew_.Rslt_month_num] - List_adp_.Base1;
byte[] msg_key = name_ary[hebrew_month];
return wiki.Msg_mgr().Val_by_key_obj(msg_key);
}
private static final byte[][] Month_name_full_ary = new byte[][]
{ Bry_.new_a7("hebrew-calendar-m1"), Bry_.new_a7("hebrew-calendar-m2"), Bry_.new_a7("hebrew-calendar-m3")
, Bry_.new_a7("hebrew-calendar-m4"), Bry_.new_a7("hebrew-calendar-m5"), Bry_.new_a7("hebrew-calendar-m6")
, Bry_.new_a7("hebrew-calendar-m7"), Bry_.new_a7("hebrew-calendar-m8"), Bry_.new_a7("hebrew-calendar-m9")
, Bry_.new_a7("hebrew-calendar-m10"), Bry_.new_a7("hebrew-calendar-m11"), Bry_.new_a7("hebrew-calendar-m12")
, Bry_.new_a7("hebrew-calendar-m6a"), Bry_.new_a7("hebrew-calendar-m6b")
};
private static final byte[][] Month_name_gen_ary = new byte[][]
{ Bry_.new_a7("hebrew-calendar-m1-gen"), Bry_.new_a7("hebrew-calendar-m2-gen"), Bry_.new_a7("hebrew-calendar-m3-gen")
, Bry_.new_a7("hebrew-calendar-m4-gen"), Bry_.new_a7("hebrew-calendar-m5-gen"), Bry_.new_a7("hebrew-calendar-m6-gen")
, Bry_.new_a7("hebrew-calendar-m7-gen"), Bry_.new_a7("hebrew-calendar-m8-gen"), Bry_.new_a7("hebrew-calendar-m9-gen")
, Bry_.new_a7("hebrew-calendar-m10-gen"), Bry_.new_a7("hebrew-calendar-m11-gen"), Bry_.new_a7("hebrew-calendar-m12-gen")
, Bry_.new_a7("hebrew-calendar-m6a-gen"), Bry_.new_a7("hebrew-calendar-m6b-gen")
};
public static final int
Rslt_year_num = 0
, Rslt_month_num = 1
, Rslt_day_num = 2
, Rslt_month_days_count = 3
;
private static final String[][] Numeral_tbls = new String[][]
{ new String[] {"", "א", "ב", "ג", "ד", "ה", "ו", "ז", "ח", "ט", "י"}
, new String[] {"", "י", "כ", "ל", "מ", "נ", "ס", "ע", "פ", "צ", "ק"}
, new String[] {"", "ק", "ר", "ש", "ת", "תק", "תר", "תש", "תת", "תתק", "תתר"}
, new String[] {"", "א", "ב", "ג", "ד", "ה", "ו", "ז", "ח", "ט", "י"}
};
public static String Calc_hebrew_numeral(int num) {
if (num > 9999 || num <= 0)
return Int_.Xto_str(num);
String tmp = "";
int pow10 = 1000;
for (int i = 3; i >= 0; pow10 /= 10, i--) {
if (num >= pow10) {
if (num == 15 || num == 16) {
tmp += Numeral_tbls[0][9] + Numeral_tbls[0][num - 9];
num = 0;
} else {
tmp += Numeral_tbls[i][(int)(num / pow10)];
if (pow10 == 1000)
tmp += "'";
}
}
num = num % pow10;
}
String rv = "";
int tmp_len = String_.Len(tmp);
if (tmp_len == 2) {
rv = tmp + "'";
}
else {
rv = String_.Mid(tmp, 0, tmp_len - 1) + "\"";
rv += String_.Mid(tmp, tmp_len - 1);
}
int rv_len = String_.Len(rv);
String start = String_.Mid(rv, 0, rv_len - 1);
String end = String_.Mid(rv, rv_len - 1);
if (String_.Eq(end, "כ"))
rv = start + "ך";
else if (String_.Eq(end, "מ"))
rv = start + "ם";
else if (String_.Eq(end, "נ"))
rv = start + "ן";
else if (String_.Eq(end, "פ"))
rv = start + "ף";
else if (String_.Eq(end, "צ"))
rv = start + "ץ";
return rv;
class Pft_fmt_itm_iranian_year_idx implements Pft_fmt_itm {
public int TypeId() {return Pft_fmt_itm_.Tid_iranian_year_idx;}
public void Fmt(Bry_bfr bfr, Xowe_wiki wiki, Xol_lang lang, DateAdp date, Pft_func_formatdate_bldr bldr) {
int[] seg_ary = Pft_fmt_itm_iranian.Calc_date(date);
bfr.Add_int_variable(seg_ary[Pft_fmt_itm_iranian.Rslt__year]);
}
}
class Pft_fmt_itm_iranian_month_idx implements Pft_fmt_itm {
public int TypeId() {return Pft_fmt_itm_.Tid_iranian_month_idx;}
public void Fmt(Bry_bfr bfr, Xowe_wiki wiki, Xol_lang lang, DateAdp date, Pft_func_formatdate_bldr bldr) {
int[] seg_ary = Pft_fmt_itm_iranian.Calc_date(date);
bfr.Add_int_variable(seg_ary[Pft_fmt_itm_iranian.Rslt__month]);
}
}
class Pft_fmt_itm_iranian_day_idx implements Pft_fmt_itm {
public int TypeId() {return Pft_fmt_itm_.Tid_iranian_day_idx;}
public void Fmt(Bry_bfr bfr, Xowe_wiki wiki, Xol_lang lang, DateAdp date, Pft_func_formatdate_bldr bldr) {
int[] seg_ary = Pft_fmt_itm_iranian.Calc_date(date);
bfr.Add_int_variable(seg_ary[Pft_fmt_itm_iranian.Rslt__day]);
}
}
class Pft_fmt_itm_iranian_month_name implements Pft_fmt_itm {
public int TypeId() {return Pft_fmt_itm_.Tid_iranian_month_name;}
public void Fmt(Bry_bfr bfr, Xowe_wiki wiki, Xol_lang lang, DateAdp date, Pft_func_formatdate_bldr bldr) {
bfr.Add(Pft_fmt_itm_iranian.Get_month_name(wiki, date));
}
}
class Pft_fmt_itm_hijiri_year_idx implements Pft_fmt_itm {
public int TypeId() {return Pft_fmt_itm_.Tid_hijiri_year_idx;}
public void Fmt(Bry_bfr bfr, Xowe_wiki wiki, Xol_lang lang, DateAdp date, Pft_func_formatdate_bldr bldr) {
int[] seg_ary = Pft_fmt_itm_hijiri.Calc_date(date);
bfr.Add_int_variable(seg_ary[Pft_fmt_itm_hijiri.Rslt__year]);
}
}
class Pft_fmt_itm_hijiri_month_idx implements Pft_fmt_itm {
public int TypeId() {return Pft_fmt_itm_.Tid_hijiri_month_idx;}
public void Fmt(Bry_bfr bfr, Xowe_wiki wiki, Xol_lang lang, DateAdp date, Pft_func_formatdate_bldr bldr) {
int[] seg_ary = Pft_fmt_itm_hijiri.Calc_date(date);
bfr.Add_int_variable(seg_ary[Pft_fmt_itm_hijiri.Rslt__month]);
}
}
class Pft_fmt_itm_hijiri_day_idx implements Pft_fmt_itm {
public int TypeId() {return Pft_fmt_itm_.Tid_hijiri_day_idx;}
public void Fmt(Bry_bfr bfr, Xowe_wiki wiki, Xol_lang lang, DateAdp date, Pft_func_formatdate_bldr bldr) {
int[] seg_ary = Pft_fmt_itm_hijiri.Calc_date(date);
bfr.Add_int_variable(seg_ary[Pft_fmt_itm_hijiri.Rslt__day]);
}
}
class Pft_fmt_itm_hijiri_month_name implements Pft_fmt_itm {
public int TypeId() {return Pft_fmt_itm_.Tid_hijiri_month_name;}
public void Fmt(Bry_bfr bfr, Xowe_wiki wiki, Xol_lang lang, DateAdp date, Pft_func_formatdate_bldr bldr) {
bfr.Add(Pft_fmt_itm_hijiri.Get_month_name(wiki, date));
}
}

View File

@@ -0,0 +1,258 @@
/*
XOWA: the XOWA Offline Wiki Application
Copyright (C) 2012 gnosygnu@gmail.com
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as
published by the Free Software Foundation, either version 3 of the
License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
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.times; import gplx.*; import gplx.xowa.*; import gplx.xowa.xtns.*; import gplx.xowa.xtns.pfuncs.*;
class Pft_fmt_itm_hebrew_ {
public static int Calc_hebrew_year_num_start(int year) {
int year_minus_1 = year - 1;
int a = (12 * year_minus_1 + 17) % 19;
int b = year_minus_1 % 4;
double m = 32.044093161144d + 1.5542417966212d * a + b / 4.0 - 0.0031777940220923d * year_minus_1;
if (m < 0)
m--;
int mar = (int)m;
if (m < 0)
m++;
m -= mar;
int c = (mar + 3 * year_minus_1 + 5 * b + 5) % 7;
if (c == 0 && a > 11 && m >= 0.89772376543210d)
mar++;
else if (c == 1 && a > 6 && m >= 0.63287037037037d)
mar += 2;
else if (c == 2 || c == 4 || c == 6)
mar++;
double year_minus_3761 = year - 3761;
mar += (int)(year_minus_3761 / 100 ) - (int)(year_minus_3761 / 400) - 24;
return mar;
}
private static final int[] Hebrew_date_rslt = new int[4];
public static int[] Calc_hebrew_date(DateAdp date) {
synchronized (Hebrew_date_rslt) {
Calc_hebrew_date(Hebrew_date_rslt, date.Year(), date.Month(), date.Day());
return Hebrew_date_rslt;
}
}
public static boolean Calc_hebrew_date(int[] rv, int year, int month, int day) { // REF.MW:Language.php|tsToHebrew
// Calculate Hebrew year
int hebrewYear = year + 3760;
// Month number when September = 1, August = 12
month += 4;
if (month > 12) {
// Next year
month -= 12;
year++;
hebrewYear++;
}
// Calculate day of year from 1 September
int dayOfYear = day;
for (int i = 1; i < month; i++) {
if (i == 6) {
// February
dayOfYear += 28;
// Check if the year is leap
if (year % 400 == 0 || (year % 4 == 0 && year % 100 > 0)) {
dayOfYear++;
}
} else if (i == 8 || i == 10 || i == 1 || i == 3) {
dayOfYear += 30;
} else {
dayOfYear += 31;
}
}
// Calculate the start of the Hebrew year
int start = Calc_hebrew_year_num_start(hebrewYear);
// Calculate next year's start
int nextStart = 0;
if (dayOfYear <= start) {
// Day is before the start of the year - it is the previous year
// Next year's start
nextStart = start;
// Previous year
year--;
hebrewYear--;
// Add days since previous year's 1 September
dayOfYear += 365;
if ((year % 400 == 0) || (year % 100 != 0 && year % 4 == 0)) {
// Leap year
dayOfYear++;
}
// Start of the new (previous) year
start = Calc_hebrew_year_num_start(hebrewYear);
} else {
// Next year's start
nextStart = Calc_hebrew_year_num_start(hebrewYear + 1);
}
// Calculate Hebrew day of year
int hebrewDayOfYear = dayOfYear - start;
// Difference between year's days
int diff = nextStart - start;
// Add 12 (or 13 for leap years) days to ignore the difference between
// Hebrew and Gregorian year (353 at least vs. 365/6) - now the
// difference is only about the year type
if ((year % 400 == 0) || (year % 100 != 0 && year % 4 == 0)) {
diff += 13;
} else {
diff += 12;
}
// Check the year pattern, and is leap year
// 0 means an incomplete year, 1 means a regular year, 2 means a complete year
// This is mod 30, to work on both leap years (which add 30 days of Adar I)
// and non-leap years
int yearPattern = diff % 30;
// Check if leap year
boolean isLeap = diff >= 30;
// Calculate day in the month from number of day in the Hebrew year
// Don't check Adar - if the day is not in Adar, we will stop before;
// if it is in Adar, we will use it to check if it is Adar I or Adar II
int hebrewDay = hebrewDayOfYear;
int hebrewMonth = 1;
int days = 0;
while (hebrewMonth <= 12) {
// Calculate days in this month
if (isLeap && hebrewMonth == 6) {
// Adar in a leap year
if (isLeap) {
// Leap year - has Adar I, with 30 days, and Adar II, with 29 days
days = 30;
if (hebrewDay <= days) {
// Day in Adar I
hebrewMonth = 13;
} else {
// Subtract the days of Adar I
hebrewDay -= days;
// Try Adar II
days = 29;
if (hebrewDay <= days) {
// Day in Adar II
hebrewMonth = 14;
}
}
}
} else if (hebrewMonth == 2 && yearPattern == 2) {
// Cheshvan in a complete year (otherwise as the rule below)
days = 30;
} else if (hebrewMonth == 3 && yearPattern == 0) {
// Kislev in an incomplete year (otherwise as the rule below)
days = 29;
} else {
// Odd months have 30 days, even have 29
days = 30 - (hebrewMonth - 1) % 2;
}
if (hebrewDay <= days) {
// In the current month
break;
} else {
// Subtract the days of the current month
hebrewDay -= days;
// Try in the next month
hebrewMonth++;
}
}
rv[0] = hebrewYear;
rv[1] = hebrewMonth;
rv[2] = hebrewDay;
rv[3] = days;
return true;
}
public static byte[] Get_hebrew_month_name_full(Xowe_wiki wiki, DateAdp date) {return Get_hebrew_month_name(wiki, date, Month_name_full_ary);}
public static byte[] Get_hebrew_month_name_gen(Xowe_wiki wiki, DateAdp date) {return Get_hebrew_month_name(wiki, date, Month_name_gen_ary);}
private static byte[] Get_hebrew_month_name(Xowe_wiki wiki, DateAdp date, byte[][] name_ary) {
int[] hebrew_date = Pft_fmt_itm_hebrew_.Calc_hebrew_date(date);
int hebrew_month = hebrew_date[Pft_fmt_itm_hebrew_.Rslt_month_num] - List_adp_.Base1;
byte[] msg_key = name_ary[hebrew_month];
return wiki.Msg_mgr().Val_by_key_obj(msg_key);
}
private static final byte[][] Month_name_full_ary = new byte[][]
{ Bry_.new_a7("hebrew-calendar-m1"), Bry_.new_a7("hebrew-calendar-m2"), Bry_.new_a7("hebrew-calendar-m3")
, Bry_.new_a7("hebrew-calendar-m4"), Bry_.new_a7("hebrew-calendar-m5"), Bry_.new_a7("hebrew-calendar-m6")
, Bry_.new_a7("hebrew-calendar-m7"), Bry_.new_a7("hebrew-calendar-m8"), Bry_.new_a7("hebrew-calendar-m9")
, Bry_.new_a7("hebrew-calendar-m10"), Bry_.new_a7("hebrew-calendar-m11"), Bry_.new_a7("hebrew-calendar-m12")
, Bry_.new_a7("hebrew-calendar-m6a"), Bry_.new_a7("hebrew-calendar-m6b")
};
private static final byte[][] Month_name_gen_ary = new byte[][]
{ Bry_.new_a7("hebrew-calendar-m1-gen"), Bry_.new_a7("hebrew-calendar-m2-gen"), Bry_.new_a7("hebrew-calendar-m3-gen")
, Bry_.new_a7("hebrew-calendar-m4-gen"), Bry_.new_a7("hebrew-calendar-m5-gen"), Bry_.new_a7("hebrew-calendar-m6-gen")
, Bry_.new_a7("hebrew-calendar-m7-gen"), Bry_.new_a7("hebrew-calendar-m8-gen"), Bry_.new_a7("hebrew-calendar-m9-gen")
, Bry_.new_a7("hebrew-calendar-m10-gen"), Bry_.new_a7("hebrew-calendar-m11-gen"), Bry_.new_a7("hebrew-calendar-m12-gen")
, Bry_.new_a7("hebrew-calendar-m6a-gen"), Bry_.new_a7("hebrew-calendar-m6b-gen")
};
public static final int
Rslt_year_num = 0
, Rslt_month_num = 1
, Rslt_day_num = 2
, Rslt_month_days_count = 3
;
private static final String[][] Numeral_tbls = new String[][]
{ new String[] {"", "א", "ב", "ג", "ד", "ה", "ו", "ז", "ח", "ט", "י"}
, new String[] {"", "י", "כ", "ל", "מ", "נ", "ס", "ע", "פ", "צ", "ק"}
, new String[] {"", "ק", "ר", "ש", "ת", "תק", "תר", "תש", "תת", "תתק", "תתר"}
, new String[] {"", "א", "ב", "ג", "ד", "ה", "ו", "ז", "ח", "ט", "י"}
};
public static String Calc_hebrew_numeral(int num) {
if (num > 9999 || num <= 0)
return Int_.Xto_str(num);
String tmp = "";
int pow10 = 1000;
for (int i = 3; i >= 0; pow10 /= 10, i--) {
if (num >= pow10) {
if (num == 15 || num == 16) {
tmp += Numeral_tbls[0][9] + Numeral_tbls[0][num - 9];
num = 0;
} else {
tmp += Numeral_tbls[i][(int)(num / pow10)];
if (pow10 == 1000)
tmp += "'";
}
}
num = num % pow10;
}
String rv = "";
int tmp_len = String_.Len(tmp);
if (tmp_len == 2) {
rv = tmp + "'";
}
else {
rv = String_.Mid(tmp, 0, tmp_len - 1) + "\"";
rv += String_.Mid(tmp, tmp_len - 1);
}
int rv_len = String_.Len(rv);
String start = String_.Mid(rv, 0, rv_len - 1);
String end = String_.Mid(rv, rv_len - 1);
if (String_.Eq(end, "כ"))
rv = start + "ך";
else if (String_.Eq(end, "מ"))
rv = start + "ם";
else if (String_.Eq(end, "נ"))
rv = start + "ן";
else if (String_.Eq(end, "פ"))
rv = start + "ף";
else if (String_.Eq(end, "צ"))
rv = start + "ץ";
return rv;
}
}

View File

@@ -0,0 +1,78 @@
/*
XOWA: the XOWA Offline Wiki Application
Copyright (C) 2012 gnosygnu@gmail.com
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as
published by the Free Software Foundation, either version 3 of the
License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
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.times; import gplx.*; import gplx.xowa.*; import gplx.xowa.xtns.*; import gplx.xowa.xtns.pfuncs.*;
class Pft_fmt_itm_hijiri {
private static final int[] tmp_rslt = new int[3];
public static int[] Calc_date(DateAdp date) {
synchronized (tmp_rslt) {
Calc_date(tmp_rslt, date.Year(), date.Month(), date.Day());
return tmp_rslt;
}
}
public static boolean Calc_date(int[] rv, int greg_y, int greg_m, int greg_d) {
int hiji_d = greg_d;
int hiji_m = greg_m;
int hiji_y = greg_y;
int tmp_jd = 0;
if (
(hiji_y > 1582) || ((hiji_y == 1582) && (hiji_m > 10)) ||
((hiji_y == 1582) && (hiji_m == 10) && (hiji_d > 14))
)
{
tmp_jd = (int)((1461 * (hiji_y + 4800 + (int)((hiji_m - 14) / 12))) / 4) +
(int)((367 * (hiji_m - 2 - 12 * ((int)((hiji_m - 14) / 12)))) / 12) -
(int)((3 * (int)(((hiji_y + 4900 + (int)((hiji_m - 14) / 12)) / 100))) / 4) +
hiji_d - 32075;
} else {
tmp_jd = 367 * hiji_y - (int)((7 * (hiji_y + 5001 + (int)((hiji_m - 9) / 7))) / 4) +
(int)((275 * hiji_m) / 9) + hiji_d + 1729777;
}
int tmp_l = tmp_jd -1948440 + 10632;
int tmp_n = (int)((tmp_l - 1) / 10631);
tmp_l = tmp_l - 10631 * tmp_n + 354;
int tmp_j = ((int)((10985 - tmp_l) / 5316)) * ((int)((50 * tmp_l) / 17719)) + ((int)(tmp_l / 5670)) * ((int)((43 * tmp_l) / 15238));
tmp_l = tmp_l - ((int)((30 - tmp_j) / 15)) * ((int)((17719 * tmp_j) / 50)) - ((int)(tmp_j / 16)) * ((int)((15238 * tmp_j) / 43)) + 29;
hiji_m = (int)((24 * tmp_l) / 709);
hiji_d = tmp_l - (int)((709 * hiji_m) / 24);
hiji_y = 30 * tmp_n + tmp_j - 30;
rv[0] = hiji_y;
rv[1] = hiji_m;
rv[2] = hiji_d;
return true;
}
public static byte[] Get_month_name(Xowe_wiki wiki, DateAdp date) {
int[] seg_ary = Calc_date(date);
int m = seg_ary[Rslt__month] - List_adp_.Base1;
byte[] msg_key = Month_names[m];
return wiki.Msg_mgr().Val_by_key_obj(msg_key);
}
private static final byte[][] Month_names = new byte[][]
{ Bry_.new_a7("hijiri-calendar-m1"), Bry_.new_a7("hijiri-calendar-m2"), Bry_.new_a7("hijiri-calendar-m3")
, Bry_.new_a7("hijiri-calendar-m4"), Bry_.new_a7("hijiri-calendar-m5"), Bry_.new_a7("hijiri-calendar-m6")
, Bry_.new_a7("hijiri-calendar-m7"), Bry_.new_a7("hijiri-calendar-m8"), Bry_.new_a7("hijiri-calendar-m9")
, Bry_.new_a7("hijiri-calendar-m10"), Bry_.new_a7("hijiri-calendar-m11"), Bry_.new_a7("hijiri-calendar-m12")
};
public static final int
Rslt__year = 0
, Rslt__month = 1
, Rslt__day = 2
;
}

View File

@@ -0,0 +1,95 @@
/*
XOWA: the XOWA Offline Wiki Application
Copyright (C) 2012 gnosygnu@gmail.com
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as
published by the Free Software Foundation, either version 3 of the
License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
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.times; import gplx.*; import gplx.xowa.*; import gplx.xowa.xtns.*; import gplx.xowa.xtns.pfuncs.*;
class Pft_fmt_itm_iranian {
private static final int[] Md__greg = new int[] { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
private static final int[] Md__iran = new int[] { 31, 31, 31, 31, 31, 31, 30, 30, 30, 30, 30, 29 };
private static final int[] tmp_rslt = new int[3];
public static int[] Calc_date(DateAdp date) {
synchronized (Md__iran) {
Calc_date(tmp_rslt, date.Year(), date.Month(), date.Day());
return tmp_rslt;
}
}
public static boolean Calc_date(int[] rv, int greg_y, int greg_m, int greg_d) { // REF.MW:Language.php|tsToIranian
greg_y -= 1600;
--greg_m;
--greg_d;
// Days passed from the beginning (including leap years)
int greg_doy = 365 * greg_y
+ (int)((greg_y + 3) / 4)
- (int)((greg_y + 99) / 100)
+ (int)((greg_y + 399) / 400)
;
// Add days of the past months of this year
for (int i = 0; i < greg_m; ++i) {
greg_doy += Md__greg[i];
}
// Leap years
if (greg_m > 1 && ((greg_y % 4 == 0 && greg_y % 100 != 0 || (greg_y % 400 == 0))))
greg_doy++;
// Days passed in current month
greg_doy += greg_d;
int iran_doy = greg_doy - 79;
int iran_np = (int)(iran_doy / 12053);
iran_doy %= 12053;
int iran_y = 979 + 33 * iran_np + 4 * (int)(iran_doy / 1461);
iran_doy %= 1461;
if (iran_doy >= 366) {
iran_y += (int)((iran_doy - 1) / 365);
iran_doy = (int)((iran_doy - 1) % 365);
}
int j = 0;
for (j = 0; j < 11 && iran_doy >= Md__iran[j]; ++j)
iran_doy -= Md__iran[j];
int iran_m = j + 1;
int iran_d = iran_doy + 1;
rv[0] = iran_y;
rv[1] = iran_m;
rv[2] = iran_d;
return true;
}
public static byte[] Get_month_name(Xowe_wiki wiki, DateAdp date) {
int[] seg_ary = Calc_date(date);
int m = seg_ary[Rslt__month] - List_adp_.Base1;
byte[] msg_key = Month_names[m];
return wiki.Msg_mgr().Val_by_key_obj(msg_key);
}
private static final byte[][] Month_names = new byte[][]
{ Bry_.new_a7("iranian-calendar-m1"), Bry_.new_a7("iranian-calendar-m2"), Bry_.new_a7("iranian-calendar-m3")
, Bry_.new_a7("iranian-calendar-m4"), Bry_.new_a7("iranian-calendar-m5"), Bry_.new_a7("iranian-calendar-m6")
, Bry_.new_a7("iranian-calendar-m7"), Bry_.new_a7("iranian-calendar-m8"), Bry_.new_a7("iranian-calendar-m9")
, Bry_.new_a7("iranian-calendar-m10"), Bry_.new_a7("iranian-calendar-m11"), Bry_.new_a7("iranian-calendar-m12")
};
public static final int
Rslt__year = 0
, Rslt__month = 1
, Rslt__day = 2
;
}

View File

@@ -20,18 +20,26 @@ import org.junit.*;
public class Pft_func_time_foreign_tst {
@Before public void init() {fxt.Clear();} private Pft_func_time_foreign_fxt fxt = new Pft_func_time_foreign_fxt();
@After public void term() {fxt.Term();}
@Test public void Roman() {fxt.Test_parse("{{#time:xrY|2012}}" , "MMXII");}
@Test public void Thai() {fxt.Test_parse("{{#time:xkY|2012}}" , "2555");}
@Test public void Minguo() {fxt.Test_parse("{{#time:xoY|2012}}" , "101");}
@Test public void Hebrew_year_num() {fxt.Test_parse("{{#time:xjY|2012-01-02}}" , "5772");}
@Test public void Hebrew_month_num() {fxt.Test_parse("{{#time:xjn|2012-01-02}}" , "4");}
@Test public void Hebrew_day_num() {fxt.Test_parse("{{#time:xjj|2012-01-02}}" , "7");}
@Test public void Hebrew_month_days_count() {fxt.Test_parse("{{#time:xjt|2012-01-02}}" , "29");}
@Test public void Hebrew_month_name_full() {fxt.Init_msg("hebrew-calendar-m4" , "Tevet").Test_parse("{{#time:xjF|2012-01-02}}" , "Tevet");}
@Test public void Hebrew_month_name_gen() {fxt.Init_msg("hebrew-calendar-m4-gen" , "Tevet").Test_parse("{{#time:xjx|2012-01-02}}" , "Tevet");}
@Test public void Hebrew_numeral() {fxt.Test_parse("{{#time:xh}}" , "");}
@Test public void Hebrew_numeral_2() {fxt.Test_parse("{{#time:xhxjY|2014}}" , "ה'תשע\"ד");}
@Test public void Roman_various() {
@Test public void Hebrew__year_num() {fxt.Test_parse("{{#time:xjY|2012-01-02}}" , "5772");}
@Test public void Hebrew__month_num() {fxt.Test_parse("{{#time:xjn|2012-01-02}}" , "4");}
@Test public void Hebrew__day_num() {fxt.Test_parse("{{#time:xjj|2012-01-02}}" , "7");}
@Test public void Hebrew__month_days_count() {fxt.Test_parse("{{#time:xjt|2012-01-02}}" , "29");}
@Test public void Hebrew__month_name_full() {fxt.Init_msg("hebrew-calendar-m4" , "Tevet").Test_parse("{{#time:xjF|2012-01-02}}" , "Tevet");}
@Test public void Hebrew__month_name_gen() {fxt.Init_msg("hebrew-calendar-m4-gen" , "Tevet").Test_parse("{{#time:xjx|2012-01-02}}" , "Tevet");}
@Test public void Hebrew__numeral() {fxt.Test_parse("{{#time:xh}}" , "");}
@Test public void Hebrew__numeral_2() {fxt.Test_parse("{{#time:xhxjY|2014}}" , "ה'תשע\"ד");}
@Test public void Iranian__year_idx() {fxt.Test_parse("{{#time:xiY|2012-01-02}}" , "1390");}
@Test public void Iranian__month_idx() {fxt.Test_parse("{{#time:xin|2012-01-02}}" , "10");}
@Test public void Iranian__day_idx() {fxt.Test_parse("{{#time:xij|2012-01-02}}" , "12");}
@Test public void Iranian__month_name() {fxt.Init_msg("iranian-calendar-m10" , "Dey"); fxt.Test_parse("{{#time:xiF|2012-01-02}}" , "Dey");}
@Test public void Hijiri__year_idx() {fxt.Test_parse("{{#time:xmY|2012-01-02}}" , "1433");}
@Test public void Hijiri__month_idx() {fxt.Test_parse("{{#time:xmn|2012-01-02}}" , "2");}
@Test public void Hijiri__day_idx() {fxt.Test_parse("{{#time:xmj|2012-01-02}}" , "7");}
@Test public void Hijiri__month_name() {fxt.Init_msg("hijiri-calendar-m2" , "Safar"); fxt.Test_parse("{{#time:xmF|2012-01-02}}" , "Safar");}
@Test public void Roman__year() {fxt.Test_parse("{{#time:xrY|2012}}" , "MMXII");}
@Test public void Roman__various() {
fxt.Test_Roman( 1, "I");
fxt.Test_Roman( 2, "II");
fxt.Test_Roman( 3, "III");

View File

@@ -85,21 +85,21 @@ class Pxd_itm_sym extends Pxd_itm_base {
}
class Pxd_itm_int_dmy_14 extends Pxd_itm_base implements Pxd_itm_int_interface {
public Pxd_itm_int_dmy_14(int ary_idx, byte[] src, int digits) {this.Ctor(ary_idx); this.src = src; this.digits = digits;} private byte[] src; int digits;
public int Xto_int_or(int or) {return Bry_.Xto_int_or(src, or);}
public int Xto_int_or(int or) {return Bry_.To_int_or(src, or);}
@Override public byte Tkn_tid() {return Pxd_itm_.Tid_int_dmy_14;}
@Override public int Eval_idx() {return eval_idx;} private int eval_idx = 20;
@Override public void Time_ini(DateAdpBldr bldr) {
if (this.Seg_idx() != Pxd_itm_base.Seg_idx_null) return; // has seg_idx; already eval'd by something else
bldr.Seg_set(DateAdp_.SegIdx_year , Bry_.Xto_int_or(src, 0, 4, 0));
bldr.Seg_set(DateAdp_.SegIdx_month , Bry_.Xto_int_or(src, 4, 6, 0));
bldr.Seg_set(DateAdp_.SegIdx_year , Bry_.To_int_or(src, 0, 4, 0));
bldr.Seg_set(DateAdp_.SegIdx_month , Bry_.To_int_or(src, 4, 6, 0));
if (digits > 6) {
bldr.Seg_set(DateAdp_.SegIdx_day , Bry_.Xto_int_or(src, 6, 8, 0));
bldr.Seg_set(DateAdp_.SegIdx_day , Bry_.To_int_or(src, 6, 8, 0));
if (digits > 8) {
bldr.Seg_set(DateAdp_.SegIdx_hour , Bry_.Xto_int_or(src, 8, 10, 0));
bldr.Seg_set(DateAdp_.SegIdx_hour , Bry_.To_int_or(src, 8, 10, 0));
if (digits > 10) {
bldr.Seg_set(DateAdp_.SegIdx_minute , Bry_.Xto_int_or(src, 10, 12, 0));
bldr.Seg_set(DateAdp_.SegIdx_minute , Bry_.To_int_or(src, 10, 12, 0));
if (digits > 12)
bldr.Seg_set(DateAdp_.SegIdx_second , Bry_.Xto_int_or(src, 12, 14, 0));
bldr.Seg_set(DateAdp_.SegIdx_second , Bry_.To_int_or(src, 12, 14, 0));
}
}
}
@@ -107,14 +107,14 @@ class Pxd_itm_int_dmy_14 extends Pxd_itm_base implements Pxd_itm_int_interface {
}
class Pxd_itm_int_mhs_6 extends Pxd_itm_base implements Pxd_itm_int_interface {
public Pxd_itm_int_mhs_6(int ary_idx, byte[] src) {this.Ctor(ary_idx); this.src = src;} private byte[] src;
public int Xto_int_or(int or) {return Bry_.Xto_int_or(src, or);}
public int Xto_int_or(int or) {return Bry_.To_int_or(src, or);}
@Override public byte Tkn_tid() {return Pxd_itm_.Tid_int_hms_6;}
@Override public int Eval_idx() {return eval_idx;} private int eval_idx = 20;
@Override public void Time_ini(DateAdpBldr bldr) {
if (this.Seg_idx() != Pxd_itm_base.Seg_idx_null) return; // has seg_idx; already eval'd by something else
bldr.Seg_set(DateAdp_.SegIdx_hour , Bry_.Xto_int_or(src, 0, 2, 0));
bldr.Seg_set(DateAdp_.SegIdx_minute , Bry_.Xto_int_or(src, 2, 4, 0));
bldr.Seg_set(DateAdp_.SegIdx_second , Bry_.Xto_int_or(src, 4, 6, 0));
bldr.Seg_set(DateAdp_.SegIdx_hour , Bry_.To_int_or(src, 0, 2, 0));
bldr.Seg_set(DateAdp_.SegIdx_minute , Bry_.To_int_or(src, 2, 4, 0));
bldr.Seg_set(DateAdp_.SegIdx_second , Bry_.To_int_or(src, 4, 6, 0));
}
}
class Pxd_itm_sorter implements gplx.lists.ComparerAble {

View File

@@ -98,12 +98,13 @@ class Pxd_parser {
Pxd_itm itm = null;
switch (tkn_type) {
case Pxd_itm_.Tid_int:
int int_val = Bry_.Xto_int_or(src, tkn_bgn_pos, cur_pos, Int_.MinValue);
int int_val = Bry_.To_int_or(src, tkn_bgn_pos, cur_pos, Int_.MinValue);
if (int_val == Int_.MinValue) {} // FUTURE: warn
int digits = cur_pos - tkn_bgn_pos;
switch (digits) {
case 14:
case 8:
case 14: // yyyyMMddhhmmss
case 12: // yyyyMMddhhmm; PAGE:en.w:Boron; DATE:2015-07-29
case 8: // yyyyMMdd
itm = new Pxd_itm_int_dmy_14(tkns_len, Bry_.Mid(src, tkn_bgn_pos, cur_pos), digits); break;
case 6:
itm = new Pxd_itm_int_mhs_6(tkns_len, Bry_.Mid(src, tkn_bgn_pos, cur_pos)); break;
@@ -164,7 +165,7 @@ class Pxd_parser {
class Pxd_parser_ {
public static Btrie_slim_mgr Trie() {
if (trie == null) {
trie = Btrie_slim_mgr.ci_ascii_(); // NOTE:ci.ascii:MW_const.en
trie = Btrie_slim_mgr.ci_a7(); // NOTE:ci.ascii:MW_const.en
Init();
}
return trie;

View File

@@ -56,6 +56,7 @@ public class Pxd_parser_tst {
@Test public void Unit_day_neg_w_day() {tst_date_("30 May 2012 -1 days" , "2012-05-29");} // PAGE:en.w:Main Page
@Test public void Unit_week() {tst_date_("- 1 week" , "2012-02-26");} // PURPOSE.FIX: "week" was not being handled; error on main Page; EX:da.wikipedia.org/Main_Page
@Test public void Time_len_6() {tst_time_("041526" , "04:15:26.000");}
@Test public void Time_len_12() {tst_both_("201601020304" , "2016-01-02 03:04:00.000");} // PURPOSE: handle 12 digit datetime; PAGE:en.w:Boron; DATE:2015-07-29
@Test public void Err_one_num() {tst_time_("2" , "Invalid year: 2");} // occurs on some templates; PAGE:en.w:Voyager 1 and {{date}}
@Test public void Dmy_at_y_dot() {tst_date_("1.2.70" , "1970-02-01");} // PURPOSE: dmy when delimiter is dot
@Test public void Mdy_at_y_slash() {tst_date_("1/2/70" , "1970-01-02");} // PURPOSE: mdy when delimiter is slash

View File

@@ -26,7 +26,7 @@ public class Pfunc_ns extends Pf_func_base { // EX: {{ns:6}} -> File
byte[] val_dat_ary = Eval_argx(ctx, src, caller, self); if (val_dat_ary == Bry_.Empty) return;
int val_dat_ary_len = val_dat_ary.length;
int ns_id = Bry_.Xto_int_or(val_dat_ary, 0, val_dat_ary_len, Int_.MinValue);
int ns_id = Bry_.To_int_or(val_dat_ary, 0, val_dat_ary_len, Int_.MinValue);
if (ns_id == Int_.MinValue) {
Object o = ctx.Wiki().Ns_mgr().Names_get_or_null(val_dat_ary, 0, val_dat_ary_len);
if (o == null
@@ -46,7 +46,7 @@ public class Pfunc_ns extends Pf_func_base { // EX: {{ns:6}} -> File
}
private static Hash_adp_bry canonical;
private static void canonical_() {
canonical = Hash_adp_bry.ci_ascii_(); // ASCII:canonical English names
canonical = Hash_adp_bry.ci_a7(); // ASCII:canonical English names
for (Xow_ns ns : Xow_ns_.Canonical)
canonical_add(ns.Id(), ns.Name_bry());
}

View File

@@ -29,7 +29,7 @@ public class Pfunc_titleparts extends Pf_func_base {
// get parts_len
byte[] parts_len_ary = Pf_func_.Eval_arg_or_empty(ctx, src, caller, self, args_len, 0);
int parts_len = parts_len_ary == Bry_.Empty ? Int_.MinValue : Bry_.Xto_int_or(parts_len_ary, Int_.MaxValue);
int parts_len = parts_len_ary == Bry_.Empty ? Int_.MinValue : Bry_.To_int_or(parts_len_ary, Int_.MaxValue);
if (parts_len == Int_.MaxValue) {// len is not an int; EX: "a";
ctx.Msg_log().Add_itm_none(Pfunc_titleparts_log.Len_is_invalid, src, caller.Src_bgn(), caller.Src_end());
bb.Add(argx);
@@ -38,7 +38,7 @@ public class Pfunc_titleparts extends Pf_func_base {
// get parts_bgn
byte[] parts_bgn_arg = Pf_func_.Eval_arg_or_empty(ctx, src, caller, self, args_len, 1);
int parts_bgn = parts_bgn_arg == Bry_.Empty ? 0 : Bry_.Xto_int_or(parts_bgn_arg, Int_.MinValue);
int parts_bgn = parts_bgn_arg == Bry_.Empty ? 0 : Bry_.To_int_or(parts_bgn_arg, Int_.MinValue);
if (parts_bgn == Int_.MinValue) {// parts_bgn is not an int; EX: "a"
ctx.Msg_log().Add_itm_none(Pfunc_titleparts_log.Bgn_is_invalid, src, caller.Src_bgn(), caller.Src_end());
parts_bgn = 0; // NOTE: do not return

View File

@@ -33,11 +33,11 @@ public class Pfunc_urlfunc extends Pf_func_base { // EX: {{lc:A}} -> a
Xow_xwiki_itm xwiki = ttl.Wik_itm();
if (xwiki != null) { // xwiki exists; add as //commons.wikimedia.org/wiki/A#b?c=d
if (tid == Tid_canonical)
trg.Add(Xoh_href_parser.Href_https_bry); // "https://"
trg.Add(Xoh_href_.Bry__https); // "https://"
else
trg.Add(Xoa_consts.Url_relative_prefix); // "//"
trg.Add(xwiki.Domain_bry()) // "commons.wikimedia.org"
.Add(Xoh_href_parser.Href_wiki_bry) // "/wiki/"
.Add(Xoh_href_.Bry__wiki) // "/wiki/"
.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 {