--[===[
MODULE "mchkparametrojn" (check parametrojn)
"eo.wiktionary.org/wiki/Modulo:mchkparametrojn" <!--2025-Feb-06-->
"id.wiktionary.org/wiki/Modul:mchkparametrojn"
Purpose: performs 2 comparisons in order to check validity
of the anonymous parameters submitted to the parent, even empty
parameters can be accepted as valid and counted with the
"E" option, otherwise they are considered as an error, can check
availability of obligatory named parameters too
Utilo: efektivigas 2 komparojn por kontroli validecon
de la anonimaj parametroj transdonitaj al la vokanto, ecx malplenaj
parametroj povas esti akceptitaj kiel validaj kaj alsumigataj kun la
"E" opcio, alimaniere ili estas pritraktataj kiel eraro, povas ankaux
kontroli disponeblon de devigaj nomitaj parametroj
Manfaat: melaksanakan 2 perbandingan untuk mengontrol validitas
parameter anonim dikirim kepada pemanggil, bahkan parameter
kosong bisa ... dan dihitung dengan opsi "E" ... parameter bernama
Used by templates / Uzata far sxablonoj:
* many / multaj
Required submodules / Bezonataj submoduloj:
* none / neniuj
Incoming: - 2...7 anonymous parameters
- 2 integers with lower limit (must be one digit 0...9) and
upper limit (must be 1 or 2 digits bigger or equal
the lower limit, and less or equal 63)
- optional "E" string to allow empty parameters
- optional 0...4 names of obligatory named parameters
Returned: - string "1" if the parameters are accepted, string "0" if
the parameters supplied to the caller are rejected, or this
module itself becomes victim of misuse
Note that with both WIKI and LUA empty strings and parameters are valid
and different from nonexistent strings and parameters. In practice
however empty parameters are rarely useful, therefore the default
behavior is to disallow them.
Note that the result is either "1" "accepted" or "0" "rejected" after this
module has succeeded to run. But there is a third option "module failed to
run" due to not found or timeout for example. The conditional logic in the
calling template must be aware of this.
Can theoretically be used to ensure that ZERO parameters have been
submitted, but this preferably can be done by a simple "#if"-statement:
Teorie estas uzebla por certigi ke NUL parametroj estis havigitaj,
sed tio preferinde estas farebla per simpla "#if"-ordono:
<!--enkonduko#
#protekto-->{{#if:<!--o-->{{{1|}}}<!--o-->|<!--then-->{{#inv
oke:mwhineplendu|ek}}<!--o-->|<!--else--><!--protekto#
#kerno-->"Hello world!" from template "contoh"<!--kerno#
#protekto-->}}<!--endif--><!--protekto#
#fino-->
<!--enkonduko#
#protekto-->{{#if:<!--o-->{{{1|}}}<!--o-->|<!--th
en--> = <!--o-->|<!--else--><!--protekto#
#kerno-->"Hello world!" from template "contoh"<!--kerno#
#protekto-->}}<!--endif--><!--protekto#
#fino-->
This module is unbreakable (when called with correct module name
and function name).
Cxi tiu modulo estas nerompebla (kiam vokita kun gxustaj nomo de modulo
kaj nomo de funkcio).
Usage examples / Ekzemploj de uzo:
"{{#invoke:mchkparametrojn|ek|2|4}}"
"{{#invoke:mchkparametrojn|ek|3|3|E}}"
"{{#invoke:mchkparametrojn|ek|0|1}}"
"{{#invoke:mchkparametrojn|ek|0|0}}" (deprecated usage / malpreferinda uzo)
"{{#invoke:mchkparametrojn|ek|0|0|nama|umur}}"
"<!--enkonduko#
#protekto-->{{#ifeq:<!--o-->{{#invoke:mchkparamet
rojn|ek|1|2}}<!--o-->|<!--equal-->0<!--o-->|<!--then-->{{#invoke:mwhin
eplendu|ek}}<!--o-->}}<!--endif-->{{#ifeq:<!--o-->{{#invoke:mchkparamet
rojn|ek|1|2}}<!--o-->|<!--equal-->1<!--o-->|<!--then--><!--protekto#
#kerno-->"Hello world!" from template "contoh"<!--kerno#
#protekto-->}}<!--endif--><!--protekto#
#fino-->"
Notes about the examples of "protekto":
* In all 3 examples the "kerno" part is in the else-branch of an
if-structure. This means that the "kerno" part may NOT contain
unprotected walls "|", most notably "wikitables".
* The latter example invokes "mchkparametrojn" 2 times due to the risk
of "module failed to run". Make sure that both calls are identical.
]===]
local exporttable = {}
require('strict')
------------------------------------------------------------------------
---- SOME FUNCTIONS ----
------------------------------------------------------------------------
-- Local function LFDEC1DIGIT
-- Convert 1 decimal ASCII digit to integer 0...9 (255 if invalid).
local function lfdec1digit (num1digit)
num1digit = num1digit - 48 -- may become invalid
if ((num1digit<0) or (num1digit>9)) then
num1digit = 255 -- report ERROR on invalid input digit
end--if
return num1digit
end--function lfdec1digit
------------------------------------------------------------------------
-- Local function LFNSTR12DIG2INT
-- Convert string with either 1 or 2 decimal ASCII digit:s
-- to integer 0...99 (255 if invalid).
-- Depends on functions :
-- [N] lfdec1digit
local function lfnstr12dig2int (strmasuk)
local numleeng = 0
local numletf = 255 -- preASSume guilt
local numrigt = 0
numleeng = string.len (strmasuk)
if ((numleeng==1) or (numleeng==2)) then
numletf = string.byte (strmasuk,1,1)
numletf = lfdec1digit (numletf) -- 255 if invalid, ZERO would be valid
end--if
if ((numletf~=255) and (numleeng==2)) then
numrigt = string.byte (strmasuk,2,2)
numrigt = lfdec1digit (numrigt) -- 255 if invalid, ZERO would be valid
if (numrigt==255) then
numletf = 255 -- 255 is invalid, note that ZERO would be valid
else
numletf = numletf * 10 + numrigt -- valid integer number 0...99 now
end--if
end--if
return numletf
end--function lfnstr12dig2int
------------------------------------------------------------------------
---- VARIABLES [R] ----
------------------------------------------------------------------------
function exporttable.ek (arxframent)
-- unknown type
local vartymp = 0
-- general table
local tabnamed = {} -- named params to check
-- special type "args" AKA "arx"
local arxourown = 0 -- metaized "args" from our own "frame"
local arxcaller = 0 -- metaized "args" from caller's "frame"
-- general "str"
local strtump = ""
local strret = "" -- output string
-- general "num"
local numlong = 0 -- temp
local numlowl = 0 -- lower limit
local numuppl = 0 -- upper limit
local numiter = 0 -- index iterating through parameters 2 times
local numjuml = 0 -- amount of expected named params
-- general "boo"
local booerr = false -- fatal error flag
local booemp = false -- flag allow empty parameters (default is disallow)
------------------------------------------------------------------------
---- MAIN [Z] ----
------------------------------------------------------------------------
---- SEIZE 2...7 PARAMETERS SENT FROM CALLER TO US ----
arxourown = arxframent.args -- "args" from our own "frame"
if ((arxourown[1]==nil) or (arxourown[2]==nil) or (arxourown[8])) then
booerr = true -- need 2 obligatory params, 8 are not appreciated
else
strtump = arxourown[1] -- lower limit (1 digit)
numlong = string.len (strtump)
if (numlong==1) then
numlowl = string.byte (strtump,1,1)
numlowl = lfdec1digit (numlowl) -- 255 if invalid
else
booerr = true
end--if
strtump = arxourown[2] -- upper limit (1 or 2 digits)
numuppl = lfnstr12dig2int (strtump) -- 0...99 or 255 if invalid
if ((numlowl>9) or (numuppl<numlowl) or (numuppl>63)) then
booerr = true
end--if
end--if
if (booerr==false) then
numiter = 3 -- ONE-based
numjuml = 0 -- ZERO/ONE-based
vartymp = arxourown[3] -- risk of "nil"
if (type(vartymp)=='string') then
if (vartymp=='E') then
booemp = true -- flag to allow empty parameters
numiter = 4 -- start searching named params after the "E"
end--if
end--if
while (true) do -- iterate over expected named params via anonymous params
vartymp = arxourown[numiter] -- risk of "nil"
if (type(vartymp)=='string') then
if (numjuml==4) then
booerr = true -- 7 params and no "E" this is criminal
break
end--if
numjuml = numjuml + 1 -- ONE-based -- found expected named parameter
tabnamed[numjuml] = vartymp
numiter = numiter + 1 -- ONE-based
else
break -- OK -- "numjuml" has the seized amount 0...4
end--if
end--while
end--if
---- CARRY OUT THE HARD WORK ----
arxcaller = arxframent:getParent().args -- "args" from caller's "frame"
if (booerr==false) then
numiter = 1 -- ONE-based
while (true) do -- iterate through anonymous parameters of the caller
vartymp = arxcaller[numiter]
if (vartymp==nil) then
numiter = numiter - 1 -- can be ZERO
break -- no more parameters, "numiter" holds amount of those found
else
if ((booemp==false) and (vartymp=='')) then
booerr = true
break -- empty parameter found, this is fatal
end--if
end--if
numiter = numiter + 1
end--while
if ((numiter<numlowl) or (numiter>numuppl)) then
booerr = true
end--if
end--if
if (booerr==false) then
numiter = 1 -- ONE-based
while (true) do -- iterate through expected named parameters of the caller
if (numiter>numjuml) then
break -- done
end--if
strtump = tabnamed[numiter]
vartymp = arxcaller[strtump]
if (vartymp==nil) then
booerr = true
break -- expected named parameter NOT found, this is fatal
else
if ((booemp==false) and (vartymp=='')) then
booerr = true
break -- empty parameter found without "E", this is fatal too
end--if
end--if
numiter = numiter + 1
end--while
end--if
strret = '1' -- preASSume output string to report "accepted"
if (booerr) then
strret = '0' -- change output string to report "rejected"
end--if
---- RETURN THE JUNK STRING ----
return strret -- can be only "0" or "1"
end--function
---- RETURN THE JUNK LUA TABLE ----
return exporttable