// used by HasMinValInTU and HasMaxValInTU protected void PrepareMinMaxPar(FunBase fun, List <string> footnoteNumbers) { minMaxVal = fun.GetFootnotePar <ParVarIL>(DefQuery.Par.Val, footnoteNumbers); if (minMaxVal == null) { infoStore.communicator.ReportError(new Communicator.ErrorInfo() { isWarning = false, message = $"{description.Get()}: compulsory query-parameter {DefQuery.Par.Val} missing" }); } ParBool parUnique = fun.GetFootnotePar <ParBool>(DefQuery.Par.Unique, footnoteNumbers); if (parUnique != null) { minMaxUnique = parUnique.GetBoolValue(); } ParBool parAd = fun.GetFootnotePar <ParBool>(DefQuery.Par.Adults_Only, footnoteNumbers); if (parAd != null) { minMaxAdultsOnly = parAd.GetBoolValue(); } }
protected void PrepareAgePar(FunBase fun, List <string> footnoteNumbers) // age parameters are provided by several queries { // therefore have a centralised function ... parAgeMin = fun.GetFootnotePar <ParNumber>(DefQuery.Par.AgeMin, footnoteNumbers); parAgeMax = fun.GetFootnotePar <ParNumber>(DefQuery.Par.AgeMax, footnoteNumbers); // to consider: I think age parameters are always optional // (otherwise one would need a parameter 'isOptional' and respective checks if it is false) // also see note in PrepareNMPar about getting numbers instead of just the parameters }
protected void PrepareIncomeInfoPar(FunBase fun, List <string> footnoteNumbers) // ... ditto income/info parameter { parIncome = fun.GetFootnotePar <ParVarIL>(DefQuery.Par.Income, footnoteNumbers); if (parIncome == null) { parIncome = fun.GetFootnotePar <ParVarIL>(DefQuery.Par.Info, footnoteNumbers); } if (parIncome == null) { infoStore.communicator.ReportError(new Communicator.ErrorInfo() { isWarning = false, message = $"{description.Get()}: compulsory query-parameter {DefQuery.Par.Income} missing" }); } }
// this handles the old style syntax which puts the footnote outside the brackets in context with Amount, e.g. {xyz < amount}#1 // obviously, if the Calculator moves the footnotes inside, it's too late for Amount-replacement, // but if this would be the only problem one could think of changing the order // however the Calculator would produce {xyz#1 < amount#1} which is in the case I found wrong - there is no footnote for xyz // thus this would lead to the incorrect error message "missing footnote for xyz#1" // note that for e.g. {xyz < abc}#1, moving in is justified, because the programme never could know which side is meant // summarising: treating this as "special" is anyway necessary and thus it is done with this function private string HandleOldStyleAmount(string formula, FunBase fun) { string amount = DefPar.Value.AMOUNT.ToLower(); int amountIndex = formula.IndexOf(amount); while (amountIndex >= 0) { if (amountIndex == 0 || calc.IsSymbol(formula[amountIndex - 1])) // make sure not touching abc_amount { int footnoteIndex = formula.Substring(amountIndex).IndexOf("}#"); if (footnoteIndex == -1) { return(formula); // let Calculator catch the error } footnoteIndex += amountIndex + 1; // i.e. the # after the bracket string number = string.Empty; for (int i = footnoteIndex + 1; i < formula.Length; ++i) // start on character after the # { if ((formula[i] >= '0' && formula[i] <= '9') || (formula.ToLower()[i] >= 'a' && formula.ToLower()[i] <= 'z')) { number += formula[i]; } else { break; } } ParBase parAmount = fun.GetFootnotePar <ParBase>(DefPar.Footnote.Amount, new List <string>() { number }); string replaceBy = "0"; if (parAmount != null) { replaceBy = parAmount.xmlValue; } else { infoStore.communicator.ReportError(new Communicator.ErrorInfo() { isWarning = false, message = $"{description.Get()}: missing footnote {DefPar.Footnote.Amount}({number})" }); } // if there is actually a second footnote (except #_Amount) with the same number, do not delete the footnote // allows for e.g. {yem < amount}#1, with #_Amount(1) = 12000#y and #_Level(1) = tu_whatsoever if (fun.GetFootnoteParCount(number) == 1) { formula = formula.Remove(footnoteIndex, number.Length + 1); } formula = formula.Remove(amountIndex, amount.Length); formula = formula.Insert(amountIndex, replaceBy); } amountIndex = formula.IndexOf(amount, amountIndex + 1); } return(formula); }
// currently only used by IsNtoMchild, but still make it general as future queries may make use of it protected void PrepareNMPar(FunBase fun, List <string> footnoteNumbers) { parN = fun.GetFootnotePar <ParNumber>(DefQuery.Par.N, footnoteNumbers); if (parN == null) { infoStore.communicator.ReportError(new Communicator.ErrorInfo() { isWarning = false, message = $"{description.Get()}: compulsory query-parameter {DefQuery.Par.N} missing" }); } parM = fun.GetFootnotePar <ParNumber>(DefQuery.Par.M, footnoteNumbers); if (parM == null) { infoStore.communicator.ReportError(new Communicator.ErrorInfo() { isWarning = false, message = $"{description.Get()}: compulsory query-parameter {DefQuery.Par.M} missing" }); } // note: getting the numbers and not just the parameters at this stage may be more efficient, but would make using // constants more difficult (actually happens) and a future change to ParFormula (for more flexibility) impossible }
internal override void CheckAndPrepare(FunBase fun, List <string> footnoteNumbers) { ParBase parDatabase = fun.GetFootnotePar <ParBase>(DefQuery.Par.DataBasename, footnoteNumbers); if (parDatabase != null) { isUsedDB = infoStore.IsUsedDatabase(parDatabase.xmlValue) == true ? 1.0 : 0.0; } else { infoStore.communicator.ReportError(new Communicator.ErrorInfo() { isWarning = false, message = $"{description.Get()}: compulsory query-parameter {DefQuery.Par.DataBasename} missing" }); } }
private string HandleAmount(string formula, FunBase fun) { string amount = DefPar.Value.AMOUNT.ToLower() + "#"; int amountIndex = formula.IndexOf(amount); while (amountIndex >= 0) { if (amountIndex == 0 || !calc.IsVarChar(formula[amountIndex - 1])) // make sure not touching abc_amount#1 { string number = string.Empty; for (int i = amountIndex + amount.Length; i < formula.Length; ++i) { if ((formula[i] >= '0' && formula[i] <= '9') || (formula.ToLower()[i] >= 'a' && formula.ToLower()[i] <= 'z')) { number += formula[i]; } else { break; } } ParBase parAmount = fun.GetFootnotePar <ParBase>(DefPar.Footnote.Amount, new List <string>() { number }); string replaceBy = "0"; if (parAmount != null) { replaceBy = parAmount.xmlValue; } else { infoStore.communicator.ReportError(new Communicator.ErrorInfo() { isWarning = false, message = $"{description.Get()}: missing footnote {DefPar.Footnote.Amount}({number})" }); } formula = formula.Remove(amountIndex, amount.Length + number.Length); formula = formula.Insert(amountIndex, replaceBy); } amountIndex = formula.IndexOf(amount, amountIndex + 1); } return(formula); }
/// <summary> /// checks if the standard footnote-parameters, i.e. #_LowLim, #_UpLim, #_Level, are applied on the parameter /// if so, stores them in lowLim, upLim and alternativeTU (see above) /// also provides the "cleaned" value (e.g. yem#1 -> yem) /// note that the footnote-parameters are assessed via the (mother)function (parameter fun) /// also note that the only other (not here handled) footnote-parameters are 'amount', which is handled by ParFormula /// and query parameters which will not issue a "missing" (see below) but let the query check if it can use the footnote /// </summary> protected void ExtractStandardFootnotes(string value, out string cleanedValue, FunBase fun) { List <string> numbers = GetFootnoteNumbers(value, out cleanedValue); // it's unlikely, but yem#1#3 is possible (see GetFootnoteNumbers) if (numbers.Count == 0) { return; // no footnotes } // limits (see remark in _FunInSpineBase_Lim wrt not using a common implementation for limits) pLowLim = fun.GetFootnotePar <ParFormula>(DefPar.Footnote.LowLim, numbers); if (pLowLim != null) { if (pLowLim.IsGlobal(true)) { lowLim = pLowLim.GetGlobalValue(); pLowLim = null; } else { doRunTimeLimCheck = true; } } pUpLim = fun.GetFootnotePar <ParFormula>(DefPar.Footnote.UpLim, numbers); if (pUpLim != null) { if (pUpLim.IsGlobal(true)) { upLim = pUpLim.GetGlobalValue(); pUpLim = null; } else { doRunTimeLimCheck = true; } } ParCateg pLimpriority = fun.GetFootnotePar <ParCateg>(DefPar.Footnote.LimPriority, numbers); if (pLimpriority != null) { limPri = pLimpriority.GetCateg(); } if (!doRunTimeLimCheck) // both limits available (might be double.MinValue and/or double.MaxValue, but does no harm here) { CheckLimits(ref lowLim, ref upLim); } // alternative TU ParBase parAltTU = fun.GetFootnotePar <ParBase>(DefPar.Footnote.Level, numbers); if (parAltTU != null) { alternativeTU = parAltTU.xmlValue; } // if none of the standard footnotes is defined in the function #x points to nowhere ... if (GetType() == typeof(ParQuery)) // ... except for queries, which may have own footnotes { return; // (this is slightly negligent, as it accepts e.g. IsMarried#1 without respective footnote-parameter) } if (pLowLim == null && lowLim == double.MinValue && pUpLim == null && upLim == double.MaxValue && parAltTU == null) { infoStore.communicator.ReportError(new Communicator.ErrorInfo() { isWarning = true, message = $"{description.Get()}: missing footnote parameter for {value}" }); } }