Modulo:mchkparametrojn

 MODULO
Memtesto ne disponeblas.
Ĉi tiu modulo estas multfoje bindita.
Se vi konas la eblajn sekvojn, tiam vi povas zorgeme ekredakti.
Se vi ne kuraĝas redakti tiam vi povas proponi la deziratan ŝanĝon en la diskutejo.

--[===[

MODULE "mchkparametrojn" (check parametrojn)

"eo.wiktionary.org/wiki/Modulo:mchkparametrojn" <!--2019-Jun-30-->
"id.wiktionary.org/wiki/Modul:mchkparametrojn"

Purpose: performs 2 comparisons in order to check validity
         of the anonymous parameters submitted the caller, 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 ...
         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 1 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 misuze

Note that with both WIKI and LUA empty strings and parameters are valid
and different from nonexistent strings and parameters. In practise
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-->&nbsp;=&nbsp;<!--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 chkparametrojn = {}

------------------------------------------------------------------------

---- ORDINARY LOCAL LOW LEVEL FUNCTIONS ----

------------------------------------------------------------------------

-- Local function LFDEC1DIGIT

-- Convert ASCII code of 1 decimal digit to integer

local function lfdec1digit (num1digit)
  num1digit = num1digit - 48 -- may become invalid
  if ((num1digit<0) or (num1digit>9)) then
    num1digit = 255
  end--if
  return num1digit
end--function lfdec1digit

------------------------------------------------------------------------

-- Local function LFSTR12DIG2INT

-- Convert a strig with 1 or 2 decimal digits to integer

local function lfstr12dig2int (strmasuk)
  local numleen = 0
  local numaa = 255 -- preset to "error"
  local numbb = 0
  numleen = string.len (strmasuk)
  if ((numleen==1) or (numleen==2)) then
    numaa = string.byte (strmasuk,1,1)
    numaa = lfdec1digit (numaa) -- 255 if invalid, ZERO would be valid
  end--if
  if ((numaa~=255) and (numleen==2)) then
    numbb = string.byte (strmasuk,2,2)
    numbb = lfdec1digit (numbb) -- 255 if invalid, ZERO would be valid
    if (numbb==255) then
      numaa = 255 -- 255 is invalid, note that ZERO would be valid
    else
      numaa = numaa * 10 + numbb -- valid integer number 0...99 now
    end--if
  end--if
  return numaa
end--function lfstr12dig2int

------------------------------------------------------------------------

---- MAIN EXPORTED FUNCTION ----

------------------------------------------------------------------------

function chkparametrojn.ek (arxframent)

  -- general unknown type

  local vartmp = 0     -- variable without type

  -- 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 strtmp = ""    -- temp
  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)

  ---- 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
    strtmp = arxourown[1] -- lower limit (1 digit)
    numlong = string.len (strtmp)
    if (numlong==1) then
      numlowl = string.byte (strtmp,1,1)
      numlowl = lfdec1digit (numlowl) -- 255 if invalid
    else
      booerr = true
    end--if
    strtmp = arxourown[2] -- upper limit (1 or 2 digits)
    numuppl = lfstr12dig2int (strtmp) -- 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
    vartmp = arxourown[3] -- risk of "nil"
    if (type(vartmp)=="string") then
      if (vartmp=="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
      vartmp = arxourown[numiter] -- risk of "nil"
      if (type(vartmp)=="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] = vartmp
        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
      vartmp = arxcaller[numiter]
      if (vartmp==nil) then
        numiter = numiter - 1 -- can be ZERO
        break -- no more parameters, "numiter" holds amount of those found
      else
        if ((booemp==false) and (vartmp=="")) 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
      strtmp = tabnamed[numiter]
      vartmp = arxcaller[strtmp]
      if (vartmp==nil) then
        booerr = true
        break -- expected named parameter NOT found, this is fatal
      else
        if ((booemp==false) and (vartmp=="")) 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" -- preset output string to report "accepted"
  if (booerr) then
    strret = "0" -- set 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 chkparametrojn