From d3a37179efd165d5ebb0c92d39346519ae3d0348 Mon Sep 17 00:00:00 2001
From: Enno Rehling <enno.rehling@gmail.com>
Date: Sat, 29 Sep 2018 19:32:39 +0200
Subject: [PATCH] add param.[hc], at last.

---
 src/economy.c            |   8 ++-
 src/give.c               |   5 +-
 src/give.test.c          |   1 +
 src/kernel/build.c       |   7 +-
 src/kernel/build.test.c  |  23 ++++---
 src/kernel/building.c    |   1 +
 src/kernel/config.c      | 132 +-------------------------------------
 src/kernel/config.h      |   9 ---
 src/kernel/config.test.c |   5 +-
 src/kernel/order.c       |   1 +
 src/kernel/order.test.c  |   1 +
 src/kernel/ship.c        |   1 +
 src/kernel/types.h       |  54 ----------------
 src/kernel/unit.c        |  15 ++---
 src/laws.c               |  13 +++-
 src/laws.h               |   5 +-
 src/laws.test.c          |   1 +
 src/magic.c              |   1 +
 src/move.c               |   5 +-
 src/orderfile.c          |  25 +++++---
 src/renumber.c           |   5 +-
 src/renumber.test.c      |   1 +
 src/report.c             |   7 +-
 src/reports.test.c       |   2 +-
 src/skill.c              |   2 +
 src/spy.c                |   3 +-
 src/spy.test.c           |   2 +
 src/study.c              |   3 +-
 src/tests.c              |   6 +-
 src/tests.h              |   5 +-
 src/util/CMakeLists.txt  |   2 +
 src/util/keyword.h       |   1 -
 src/util/param.c         | 134 +++++++++++++++++++++++++++++++++++++++
 src/util/param.h         |  77 ++++++++++++++++++++++
 34 files changed, 317 insertions(+), 246 deletions(-)
 create mode 100644 src/util/param.c
 create mode 100644 src/util/param.h

diff --git a/src/economy.c b/src/economy.c
index 15b907a25..1d3f6685f 100644
--- a/src/economy.c
+++ b/src/economy.c
@@ -20,7 +20,7 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 #ifdef _MSC_VER
 #include <platform.h>
 #endif
-#include <kernel/config.h>
+
 #include "economy.h"
 
 #include "alchemy.h"
@@ -45,10 +45,13 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 
 /* kernel includes */
 #include "kernel/ally.h"
+#include "kernel/attrib.h"
 #include "kernel/building.h"
 #include "kernel/calendar.h"
+#include "kernel/config.h"
 #include "kernel/curse.h"
 #include "kernel/equipment.h"
+#include "kernel/event.h"
 #include "kernel/faction.h"
 #include "kernel/item.h"
 #include "kernel/messages.h"
@@ -64,13 +67,12 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 #include "kernel/unit.h"
 
 /* util includes */
-#include <kernel/attrib.h>
 #include <util/base36.h>
-#include <kernel/event.h>
 #include <util/goodies.h>
 #include <util/language.h>
 #include <util/lists.h>
 #include <util/log.h>
+#include "util/param.h"
 #include <util/parser.h>
 #include <util/rng.h>
 
diff --git a/src/give.c b/src/give.c
index 02d5c622d..4b1dbb0ac 100644
--- a/src/give.c
+++ b/src/give.c
@@ -25,6 +25,8 @@
 #include <attributes/racename.h>
 
  /* kernel includes */
+#include <kernel/attrib.h>
+#include <kernel/event.h>
 #include <kernel/ally.h>
 #include <kernel/build.h>
 #include <kernel/curse.h>
@@ -41,11 +43,10 @@
 #include <kernel/unit.h>
 
 /* util includes */
-#include <kernel/attrib.h>
 #include <util/base36.h>
-#include <kernel/event.h>
 #include <util/log.h>
 #include <util/macros.h>
+#include <util/param.h>
 #include <util/parser.h>
 
 /* libc includes */
diff --git a/src/give.test.c b/src/give.test.c
index 9c07c8cd0..06c0ecf96 100644
--- a/src/give.test.c
+++ b/src/give.test.c
@@ -16,6 +16,7 @@
 #include <util/base36.h>
 #include <util/language.h>
 #include <util/message.h>
+#include <util/param.h>
 
 #include <CuTest.h>
 #include <tests.h>
diff --git a/src/kernel/build.c b/src/kernel/build.c
index 82c629b0b..a3b1c0e50 100644
--- a/src/kernel/build.c
+++ b/src/kernel/build.c
@@ -33,10 +33,12 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 /* kernel includes */
 #include <kernel/ally.h>
 #include <kernel/alliance.h>
-#include <kernel/connection.h>
+#include <kernel/attrib.h>
 #include <kernel/building.h>
 #include <kernel/config.h>
+#include <kernel/connection.h>
 #include <kernel/curse.h>
+#include <kernel/event.h>
 #include <kernel/faction.h>
 #include <kernel/group.h>
 #include <kernel/item.h>
@@ -52,12 +54,11 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 #include <kernel/unit.h>
 
 /* from libutil */
-#include <kernel/attrib.h>
 #include <util/base36.h>
-#include <kernel/event.h>
 #include <util/goodies.h>
 #include <util/language.h>
 #include <util/log.h>
+#include <util/param.h>
 #include <util/parser.h>
 #include <util/resolve.h>
 
diff --git a/src/kernel/build.test.c b/src/kernel/build.test.c
index 9bae742c2..2607b2dfb 100644
--- a/src/kernel/build.test.c
+++ b/src/kernel/build.test.c
@@ -1,19 +1,24 @@
+#ifdef _MSC_VER
 #include <platform.h>
-#include <kernel/config.h>
+#endif
 
-#include <kernel/messages.h>
 #include "alchemy.h"
-#include "types.h"
 #include "build.h"
-#include "guard.h"
-#include "order.h"
-#include "unit.h"
 #include "building.h"
+#include "config.h"
 #include "faction.h"
-#include "region.h"
-#include "race.h"
+#include "guard.h"
 #include "item.h"
-#include <util/language.h>
+#include "messages.h"
+#include "order.h"
+#include "race.h"
+#include "region.h"
+#include "types.h"
+#include "unit.h"
+
+#include "util/language.h"
+#include "util/param.h"
+
 #include <CuTest.h>
 #include <tests.h>
 
diff --git a/src/kernel/building.c b/src/kernel/building.c
index 215c304e7..d97085345 100644
--- a/src/kernel/building.c
+++ b/src/kernel/building.c
@@ -45,6 +45,7 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 #include <kernel/gamedata.h>
 #include <util/language.h>
 #include <util/log.h>
+#include <util/param.h>
 #include <util/resolve.h>
 #include <util/strings.h>
 #include <util/umlaut.h>
diff --git a/src/kernel/config.c b/src/kernel/config.c
index 842324fe8..75601e831 100644
--- a/src/kernel/config.c
+++ b/src/kernel/config.c
@@ -60,6 +60,7 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 #include <util/log.h>
 #include <util/lists.h>
 #include <util/macros.h>
+#include <util/param.h>
 #include <util/parser.h>
 #include <util/path.h>
 #include <util/rand.h>
@@ -92,54 +93,6 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 #endif
 struct settings global;
 
-const char *parameters[MAXPARAMS] = {
-    "LOCALE",
-    "ALLES",
-    "JEDEM",
-    "BAUERN",
-    "BURG",
-    "EINHEIT",
-    "PRIVAT",
-    "HINTEN",
-    "KOMMANDO",
-    "KRAEUTER",
-    "NICHT",
-    "NAECHSTER",
-    "PARTEI",
-    "ERESSEA",
-    "PERSONEN",
-    "REGION",
-    "SCHIFF",
-    "SILBER",
-    "STRASSEN",
-    "TEMP",
-    "FLIEHE",
-    "GEBAEUDE",
-    "GIB",                        /* HELFE GIB */
-    "KAEMPFE",
-    "DURCHREISE",
-    "BEWACHE",
-    "ZAUBER",
-    "PAUSE",
-    "VORNE",
-    "AGGRESSIV",
-    "DEFENSIV",
-    "STUFE",
-    "HELFE",
-    "FREMDES",
-    "AURA",
-    "HINTER",
-    "VOR",
-    "ANZAHL",
-    "GEGENSTAENDE",
-    "TRAENKE",
-    "GRUPPE",
-    "PARTEITARNUNG",
-    "BAEUME",
-    "ALLIANZ",
-    "AUTO"
-};
-
 int findoption(const char *s, const struct locale *lang)
 {
     void **tokens = get_translations(lang, UT_OPTIONS);
@@ -151,78 +104,6 @@ int findoption(const char *s, const struct locale *lang)
     return NODIRECTION;
 }
 
-param_t findparam(const char *s, const struct locale * lang)
-{
-    param_t result = NOPARAM;
-    char buffer[64];
-    char * str = s ? transliterate(buffer, sizeof(buffer) - sizeof(int), s) : 0;
-
-    if (str && *str) {
-        int i;
-        void * match;
-        void **tokens = get_translations(lang, UT_PARAMS);
-        critbit_tree *cb = (critbit_tree *)*tokens;
-        if (!cb) {
-            log_warning("no parameters defined in locale %s", locale_name(lang));
-        }
-        else if (cb_find_prefix(cb, str, strlen(str), &match, 1, 0)) {
-            cb_get_kv(match, &i, sizeof(int));
-            result = (param_t)i;
-        }
-    }
-    return result;
-}
-
-param_t findparam_block(const char *s, const struct locale *lang, bool any_locale)
-{
-    param_t p;
-    if (!s || s[0] == '@') {
-        return NOPARAM;
-    }
-    p = findparam(s, lang);
-    if (any_locale && p==NOPARAM) {
-        const struct locale *loc;
-        for (loc=locales;loc;loc=nextlocale(loc)) {
-            if (loc!=lang) {
-                p = findparam(s, loc);
-                if (p==P_FACTION || p==P_GAMENAME) {
-                    break;
-                }
-            }
-        }
-    }
-    return p;
-}
-
-param_t findparam_ex(const char *s, const struct locale * lang)
-{
-    param_t result = findparam(s, lang);
-
-    if (result == NOPARAM) {
-        const building_type *btype = findbuildingtype(s, lang);
-        if (btype != NULL)
-            return P_GEBAEUDE;
-    }
-    return (result == P_BUILDING) ? P_GEBAEUDE : result;
-}
-
-bool isparam(const char *s, const struct locale * lang, param_t param)
-{
-    assert(s);
-    if (s[0] > '@') {
-        param_t p = (param == P_GEBAEUDE) ? findparam_ex(s, lang) : findparam(s, lang);
-        return p == param;
-    }
-    return false;
-}
-
-param_t getparam(const struct locale * lang)
-{
-    char token[64];
-    const char *s = gettoken(token, sizeof(token));
-    return s ? findparam(s, lang) : NOPARAM;
-}
-
 /* -- Erschaffung neuer Einheiten ------------------------------ */
 
 static const char *forbidden[] = { "t", "te", "tem", "temp", NULL };
@@ -268,17 +149,6 @@ int newcontainerid(void)
     return random_no;
 }
 
-static const char * parameter_key(int i)
-{
-    assert(i < MAXPARAMS && i >= 0);
-    return parameters[i];
-}
-
-void init_parameters(struct locale *lang) {
-    init_translations(lang, UT_PARAMS, parameter_key, MAXPARAMS);
-}
-
-
 void init_terrains_translation(const struct locale *lang) {
     void **tokens;
     const terrain_type *terrain;
diff --git a/src/kernel/config.h b/src/kernel/config.h
index e104d4a1a..95df10ae9 100644
--- a/src/kernel/config.h
+++ b/src/kernel/config.h
@@ -44,12 +44,6 @@ extern "C" {
 
     int findoption(const char *s, const struct locale *lang);
 
-    param_t findparam(const char *s, const struct locale *lang);
-    param_t findparam_block(const char *s, const struct locale *lang, bool any_locale);
-    param_t findparam_ex(const char *s, const struct locale * lang);
-    bool isparam(const char *s, const struct locale * lang, param_t param);
-    param_t getparam(const struct locale *lang);
-
     const char * game_name(void);
     const char * game_mailcmd(void);
     int game_id(void);
@@ -132,12 +126,9 @@ extern "C" {
 
     struct order *default_order(const struct locale *lang);
 
-    void init_parameters(struct locale *lang);
-
     void free_gamedata(void);
     void free_config(void);
 
-    extern const char *parameters[];
     extern settings global;
 
 #ifdef __cplusplus
diff --git a/src/kernel/config.test.c b/src/kernel/config.test.c
index e060a838e..f5d29877a 100644
--- a/src/kernel/config.test.c
+++ b/src/kernel/config.test.c
@@ -5,8 +5,11 @@
 #include <kernel/terrain.h>
 #include <kernel/unit.h>
 #include <kernel/order.h>
-#include <util/language.h>
+
 #include <util/base36.h>
+#include <util/language.h>
+#include <util/param.h>
+
 #include <kernel/attrib.h>
 
 #include <iniparser.h>
diff --git a/src/kernel/order.c b/src/kernel/order.c
index 6015b823d..c0c1e82fb 100644
--- a/src/kernel/order.c
+++ b/src/kernel/order.c
@@ -20,6 +20,7 @@
 #include "util/keyword.h"
 #include <util/language.h>
 #include <util/log.h>
+#include <util/param.h>
 #include <util/parser.h>
 #include <util/strings.h>
 
diff --git a/src/kernel/order.test.c b/src/kernel/order.test.c
index c4a55177b..d1dd6a371 100644
--- a/src/kernel/order.test.c
+++ b/src/kernel/order.test.c
@@ -5,6 +5,7 @@
 #include <kernel/skills.h>
 #include <kernel/unit.h>
 
+#include "util/param.h"
 #include <util/parser.h>
 #include <util/language.h>
 
diff --git a/src/kernel/ship.c b/src/kernel/ship.c
index 20ed49d05..6fcea4935 100644
--- a/src/kernel/ship.c
+++ b/src/kernel/ship.c
@@ -40,6 +40,7 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 #include <util/language.h>
 #include <util/lists.h>
 #include <util/log.h>
+#include <util/param.h>
 #include <util/strings.h>
 #include <util/umlaut.h>
 
diff --git a/src/kernel/types.h b/src/kernel/types.h
index 48a4326fa..d4f46ae8d 100644
--- a/src/kernel/types.h
+++ b/src/kernel/types.h
@@ -83,58 +83,6 @@ typedef enum {
   ST_FLEE
 } status_t;
 
-/* ----------------- Parameter --------------------------------- */
-
-typedef enum {
-  P_LOCALE,
-  P_ANY,
-  P_EACH,
-  P_PEASANT,
-  P_BUILDING,
-  P_UNIT,
-  P_PRIVAT,
-  P_BEHIND,
-  P_CONTROL,
-  P_HERBS,
-  P_NOT,
-  P_NEXT,
-  P_FACTION,
-  P_GAMENAME,
-  P_PERSON,
-  P_REGION,
-  P_SHIP,
-  P_MONEY,
-  P_ROAD,
-  P_TEMP,
-  P_FLEE,
-  P_GEBAEUDE,
-  P_GIVE,
-  P_FIGHT,
-  P_TRAVEL,
-  P_GUARD,
-  P_ZAUBER,
-  P_PAUSE,
-  P_VORNE,
-  P_AGGRO,
-  P_CHICKEN,
-  P_LEVEL,
-  P_HELP,
-  P_FOREIGN,
-  P_AURA,
-  P_AFTER,
-  P_BEFORE,
-  P_NUMBER,
-  P_ITEMS,
-  P_POTIONS,
-  P_GROUP,
-  P_FACTIONSTEALTH,
-  P_TREES,
-  P_ALLIANCE,
-  P_AUTO,
-  MAXPARAMS,
-  NOPARAM 
-} param_t;
-
 typedef enum {                  /* Fehler und Meldungen im Report */
   MSG_BATTLE,
   MSG_EVENT,
@@ -156,8 +104,6 @@ enum {                          /* Message-Level */
   ML_MAX
 };
 
-extern const char *parameters[MAXPARAMS];
-
 /* --------------- Reports Typen ------------------------------- */
 
 enum {
diff --git a/src/kernel/unit.c b/src/kernel/unit.c
index 00d0aeece..9b6c3e9ee 100644
--- a/src/kernel/unit.c
+++ b/src/kernel/unit.c
@@ -21,12 +21,16 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 #include "unit.h"
 
 #include "ally.h"
+#include "attrib.h"
 #include "building.h"
 #include "calendar.h"
-#include "faction.h"
-#include "group.h"
 #include "connection.h"
 #include "curse.h"
+#include "event.h"
+#include "faction.h"
+#include "gamedata.h"
+#include "group.h"
+#include "guard.h"
 #include "item.h"
 #include "move.h"
 #include "order.h"
@@ -47,18 +51,13 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 #include <spells/unitcurse.h>
 #include <spells/regioncurse.h>
 
-#include "guard.h"
-
 /* util includes */
-#include <kernel/attrib.h>
 #include <util/base36.h>
-#include <kernel/event.h>
-#include <kernel/gamedata.h>
-#include <util/strings.h>
 #include <util/language.h>
 #include <util/lists.h>
 #include <util/log.h>
 #include <util/macros.h>
+#include <util/param.h>
 #include <util/parser.h>
 #include <util/rand.h>
 #include <util/resolve.h>
diff --git a/src/laws.c b/src/laws.c
index 8cec1e51b..7e2250a59 100644
--- a/src/laws.c
+++ b/src/laws.c
@@ -80,6 +80,7 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 #include <util/log.h>
 #include <util/macros.h>
 #include <util/message.h>
+#include <util/param.h>
 #include <util/parser.h>
 #include <util/password.h>
 #include <util/path.h>
@@ -127,7 +128,17 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 #define DMRISE         0.1F     /* weekly chance that demand goes up */
 #define DMRISEHAFEN    0.2F     /* weekly chance that demand goes up with harbor */
 
-/* - exported global symbols ----------------------------------- */
+param_t findparam_ex(const char *s, const struct locale * lang)
+{
+    param_t result = findparam(s, lang);
+
+    if (result == NOPARAM) {
+        const building_type *btype = findbuildingtype(s, lang);
+        if (btype != NULL)
+            return P_GEBAEUDE;
+    }
+    return (result == P_BUILDING) ? P_GEBAEUDE : result;
+}
 
 int NewbieImmunity(void)
 {
diff --git a/src/laws.h b/src/laws.h
index 383b099ae..c30479b38 100755
--- a/src/laws.h
+++ b/src/laws.h
@@ -19,13 +19,14 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 #ifndef H_GC_LAWS
 #define H_GC_LAWS
 
-#include <kernel/types.h>
 #include <stdbool.h>
 
 #ifdef __cplusplus
 extern "C" {
 #endif
+    enum param_t;
 
+    struct locale;
     struct unit;
     struct region;
     struct building;
@@ -115,6 +116,8 @@ extern "C" {
     bool IsImmune(const struct faction *f);
     bool help_enter(struct unit *uo, struct unit *u);
 
+    enum param_t findparam_ex(const char *s, const struct locale * lang);
+
 #ifdef __cplusplus
 }
 #endif
diff --git a/src/laws.test.c b/src/laws.test.c
index 5c799a393..774ed6ecf 100644
--- a/src/laws.test.c
+++ b/src/laws.test.c
@@ -24,6 +24,7 @@
 #include <util/base36.h>
 #include <util/language.h>
 #include <util/message.h>
+#include <util/param.h>
 #include <util/rand.h>
 
 #include <CuTest.h>
diff --git a/src/magic.c b/src/magic.c
index 047ed167b..99a9ecf86 100644
--- a/src/magic.c
+++ b/src/magic.c
@@ -70,6 +70,7 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 #include <util/lists.h>
 #include <util/log.h>
 #include <util/macros.h>
+#include <util/param.h>
 #include <util/parser.h>
 #include <util/rand.h>
 #include <util/resolve.h>
diff --git a/src/move.c b/src/move.c
index 124b846ca..222588651 100644
--- a/src/move.c
+++ b/src/move.c
@@ -23,6 +23,7 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 
 /* kernel includes */
 #include "kernel/ally.h"
+#include "kernel/attrib.h"
 #include "kernel/build.h"
 #include "kernel/building.h"
 #include "kernel/calendar.h"
@@ -30,6 +31,7 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 #include "kernel/connection.h"
 #include "kernel/curse.h"
 #include "kernel/faction.h"
+#include "kernel/gamedata.h"
 #include "kernel/item.h"
 #include "kernel/messages.h"
 #include "kernel/order.h"
@@ -72,13 +74,12 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 
 /* util includes */
 #include <util/assert.h>
-#include <kernel/attrib.h>
 #include <util/base36.h>
-#include <kernel/gamedata.h>
 #include <util/language.h>
 #include <util/lists.h>
 #include <util/log.h>
 #include <util/macros.h>
+#include <util/param.h>
 #include <util/parser.h>
 #include <util/rand.h>
 #include <util/rng.h>
diff --git a/src/orderfile.c b/src/orderfile.c
index a2c7a6c87..97008f4db 100644
--- a/src/orderfile.c
+++ b/src/orderfile.c
@@ -1,5 +1,4 @@
 #include <platform.h>
-#include <kernel/config.h>
 #include "orderfile.h"
 
 #include "kernel/calendar.h"
@@ -8,12 +7,14 @@
 #include "kernel/order.h"
 #include "kernel/unit.h"
 
-#include <util/base36.h>
-#include <util/message.h>
-#include <util/language.h>
-#include <util/log.h>
-#include <util/filereader.h>
-#include <util/parser.h>
+#include "util/base36.h"
+#include "util/message.h"
+#include "util/language.h"
+#include "util/log.h"
+#include "util/filereader.h"
+#include "util/param.h"
+#include "util/parser.h"
+#include "util/order_parser.h"
 
 #include <assert.h>
 #include <stdio.h>
@@ -33,9 +34,9 @@ static unit *unitorders(input *in, faction *f)
     if (u && u->faction == f) {
         order **ordp;
 
-        if (!fval(u, UFL_ORDERS)) {
+        if (u->flags & UFL_ORDERS) {
             /* alle wiederholbaren, langen befehle werden gesichert: */
-            fset(u, UFL_ORDERS);
+            u->flags |= UFL_ORDERS;
             u->old_orders = u->orders;
             ordp = &u->old_orders;
             while (*ordp) {
@@ -125,7 +126,7 @@ static faction *factionorders(void)
     int fid = getid();
     faction *f = findfaction(fid);
 
-    if (f != NULL && !fval(f, FFL_NPC)) {
+    if (f != NULL && (f->flags & FFL_NPC) == 0) {
         char token[128];
         const char *pass = gettoken(token, sizeof(token));
 
@@ -151,6 +152,10 @@ int read_orders(input *in)
     int nfactions = 0;
     struct faction *f = NULL;
     const struct locale *lang = default_locale;
+    OP_Parser parser;
+
+    parser = OP_ParserCreate();
+    OP_ParserFree(parser);
 
     /* TODO: recognize UTF8 BOM */
     b = in->getbuf(in->data);
diff --git a/src/renumber.c b/src/renumber.c
index 8a72be2a5..a4653e1a0 100644
--- a/src/renumber.c
+++ b/src/renumber.c
@@ -1,6 +1,9 @@
 #include <platform.h>
 #include "renumber.h"
 
+#include "laws.h"
+
+#include <kernel/attrib.h>
 #include <kernel/config.h>
 #include <kernel/faction.h>
 #include <kernel/building.h>
@@ -9,8 +12,8 @@
 #include <kernel/order.h>
 #include <kernel/messages.h>
 
-#include <kernel/attrib.h>
 #include <util/base36.h>
+#include <util/param.h>
 #include <util/parser.h>
 
 #include <assert.h>
diff --git a/src/renumber.test.c b/src/renumber.test.c
index 98ca9b48b..8d44b92da 100644
--- a/src/renumber.test.c
+++ b/src/renumber.test.c
@@ -10,6 +10,7 @@
 #include <util/base36.h>
 #include <util/language.h>
 #include <util/message.h>
+#include <util/param.h>
 
 #include <stddef.h>
 #include <CuTest.h>
diff --git a/src/report.c b/src/report.c
index bc47cb1a4..1d40941c4 100644
--- a/src/report.c
+++ b/src/report.c
@@ -19,7 +19,6 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 #ifdef _MSC_VER
 #include <platform.h>
 #endif
-#include <kernel/config.h>
 
 #include "report.h"
 #include "reports.h"
@@ -50,8 +49,11 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 #include "teleport.h"
 
 /* kernel includes */
+#include "kernel/alliance.h"
 #include "kernel/ally.h"
+#include "kernel/attrib.h"
 #include "kernel/calendar.h"
+#include "kernel/config.h"
 #include "kernel/connection.h"
 #include "kernel/build.h"
 #include "kernel/building.h"
@@ -74,10 +76,8 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 #include "kernel/terrain.h"
 #include "kernel/terrainid.h"
 #include "kernel/unit.h"
-#include "kernel/alliance.h"
 
 /* util includes */
-#include <kernel/attrib.h>
 #include <util/base36.h>
 #include "util/bsdstring.h"
 #include <util/goodies.h>
@@ -86,6 +86,7 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 #include <util/log.h>
 #include <util/message.h>
 #include <util/nrmessage.h>
+#include "util/param.h"
 #include <util/rng.h>
 #include <util/strings.h>
 
diff --git a/src/reports.test.c b/src/reports.test.c
index 29f14c634..0f5ca6b1f 100644
--- a/src/reports.test.c
+++ b/src/reports.test.c
@@ -2,7 +2,7 @@
 #include "reports.h"
 
 #include "guard.h"
-#include "keyword.h"
+#include "util/keyword.h"
 #include "lighthouse.h"
 #include "laws.h"
 #include "move.h"
diff --git a/src/skill.c b/src/skill.c
index b279ab488..3d91a2598 100644
--- a/src/skill.c
+++ b/src/skill.c
@@ -5,6 +5,8 @@
 #include <util/umlaut.h>
 #include <util/language.h>
 #include <util/log.h>
+#include <util/param.h>
+
 #include <critbit.h>
 
 #include <string.h>
diff --git a/src/spy.c b/src/spy.c
index 98245e806..53a5b4321 100644
--- a/src/spy.c
+++ b/src/spy.c
@@ -27,6 +27,7 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 #include "study.h"
 
 /* kernel includes */
+#include <kernel/attrib.h>
 #include <kernel/config.h>
 #include <kernel/item.h>
 #include <kernel/faction.h>
@@ -44,8 +45,8 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 #include <attributes/stealth.h>
 
 /* util includes */
-#include <kernel/attrib.h>
 #include <util/base36.h>
+#include <util/param.h>
 #include <util/parser.h>
 #include <util/rand.h>
 #include <util/rng.h>
diff --git a/src/spy.test.c b/src/spy.test.c
index dfe2886e7..d1f616fab 100644
--- a/src/spy.test.c
+++ b/src/spy.test.c
@@ -12,8 +12,10 @@
 #include <kernel/item.h>
 #include <kernel/messages.h>
 #include <kernel/attrib.h>
+
 #include <util/language.h>
 #include <util/message.h>
+#include "util/param.h"
 #include <util/crmessage.h>
 #include <tests.h>
 
diff --git a/src/study.c b/src/study.c
index a3dfa2e33..ff961dc13 100644
--- a/src/study.c
+++ b/src/study.c
@@ -32,6 +32,7 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 #include <spells/regioncurse.h>
 
 #include <kernel/ally.h>
+#include <kernel/attrib.h>
 #include <kernel/building.h>
 #include <kernel/curse.h>
 #include <kernel/faction.h>
@@ -46,10 +47,10 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 #include <kernel/unit.h>
 
 /* util includes */
-#include <kernel/attrib.h>
 #include <util/base36.h>
 #include <util/language.h>
 #include <util/log.h>
+#include <util/param.h>
 #include <util/parser.h>
 #include <util/rand.h>
 #include <util/rng.h>
diff --git a/src/tests.c b/src/tests.c
index 2dc5bccc6..f270d9c58 100644
--- a/src/tests.c
+++ b/src/tests.c
@@ -1,11 +1,10 @@
 #include <platform.h>
 #include "tests.h"
-#include "keyword.h"
 #include "prefix.h"
 #include "reports.h"
-#include "kernel/calendar.h"
 #include "vortex.h"
 
+#include "kernel/calendar.h"
 #include <kernel/config.h>
 #include <kernel/alliance.h>
 #include <kernel/equipment.h>
@@ -24,11 +23,14 @@
 #include <kernel/spell.h>
 #include <kernel/spellbook.h>
 #include <kernel/terrain.h>
+
 #include <util/functions.h>
+#include "util/keyword.h"
 #include <util/language.h>
 #include <util/lists.h>
 #include <util/message.h>
 #include <util/log.h>
+#include "util/param.h"
 #include <util/rand.h>
 #include <util/assert.h>
 
diff --git a/src/tests.h b/src/tests.h
index 441db9e16..0f3af1972 100644
--- a/src/tests.h
+++ b/src/tests.h
@@ -1,7 +1,6 @@
 #ifndef ERESSEA_TESTS_H
 #define ERESSEA_TESTS_H
 
-#include <kernel/types.h>
 #include <stdlib.h>
 
 #ifdef __cplusplus
@@ -10,6 +9,8 @@ extern "C" {
 
     #define ASSERT_DBL_DELTA 0.001
 
+    enum param_t;
+
     struct region;
     struct unit;
     struct faction;
@@ -61,7 +62,7 @@ extern "C" {
     struct spell * test_create_spell(void);
     int test_set_item(struct unit * u, const struct item_type *itype, int value);
 
-    void test_translate_param(const struct locale *lang, param_t param, const char *text);
+    void test_translate_param(const struct locale *lang, enum param_t param, const char *text);
     const char * test_get_messagetype(const struct message *msg);
     struct message * test_find_messagetype_ex(struct message_list *msgs, const char *name, struct message *prev);
     struct message * test_find_messagetype(struct message_list *msgs, const char *name);
diff --git a/src/util/CMakeLists.txt b/src/util/CMakeLists.txt
index 61e2cf745..b4d067f57 100644
--- a/src/util/CMakeLists.txt
+++ b/src/util/CMakeLists.txt
@@ -17,6 +17,7 @@ language.test.c
 message.test.c
 # nrmessage.test.c
 # order_parser.test.c
+# param.test.c
 parser.test.c
 password.test.c
 # rand.test.c
@@ -47,6 +48,7 @@ message.c
 mt19937ar.c
 nrmessage.c
 order_parser.c
+param.c
 parser.c
 password.c
 path.c
diff --git a/src/util/keyword.h b/src/util/keyword.h
index bd4ab02d0..7bb11c485 100644
--- a/src/util/keyword.h
+++ b/src/util/keyword.h
@@ -1,7 +1,6 @@
 #ifndef H_KEYWORD_H
 #define H_KEYWORD_H
 
-#include "kernel/types.h"
 #include <stdbool.h>
 
 #ifdef __cplusplus
diff --git a/src/util/param.c b/src/util/param.c
new file mode 100644
index 000000000..31066a4a9
--- /dev/null
+++ b/src/util/param.c
@@ -0,0 +1,134 @@
+#ifdef _MSC_VER
+#include <platform.h>
+#endif
+
+#include "language.h"
+#include "log.h"
+#include "param.h"
+#include "parser.h"
+#include "umlaut.h"
+
+#include <critbit.h>
+
+#include <assert.h>
+#include <string.h>
+
+const char *parameters[MAXPARAMS] = {
+    "LOCALE",
+    "ALLES",
+    "JEDEM",
+    "BAUERN",
+    "BURG",
+    "EINHEIT",
+    "PRIVAT",
+    "HINTEN",
+    "KOMMANDO",
+    "KRAEUTER",
+    "NICHT",
+    "NAECHSTER",
+    "PARTEI",
+    "ERESSEA",
+    "PERSONEN",
+    "REGION",
+    "SCHIFF",
+    "SILBER",
+    "STRASSEN",
+    "TEMP",
+    "FLIEHE",
+    "GEBAEUDE",
+    "GIB",                        /* HELFE GIB */
+    "KAEMPFE",
+    "DURCHREISE",
+    "BEWACHE",
+    "ZAUBER",
+    "PAUSE",
+    "VORNE",
+    "AGGRESSIV",
+    "DEFENSIV",
+    "STUFE",
+    "HELFE",
+    "FREMDES",
+    "AURA",
+    "HINTER",
+    "VOR",
+    "ANZAHL",
+    "GEGENSTAENDE",
+    "TRAENKE",
+    "GRUPPE",
+    "PARTEITARNUNG",
+    "BAEUME",
+    "ALLIANZ",
+    "AUTO"
+};
+
+param_t findparam(const char *s, const struct locale * lang)
+{
+    param_t result = NOPARAM;
+    char buffer[64];
+    char * str = s ? transliterate(buffer, sizeof(buffer) - sizeof(int), s) : 0;
+
+    if (str && *str) {
+        int i;
+        void * match;
+        void **tokens = get_translations(lang, UT_PARAMS);
+        critbit_tree *cb = (critbit_tree *)*tokens;
+        if (!cb) {
+            log_warning("no parameters defined in locale %s", locale_name(lang));
+        }
+        else if (cb_find_prefix(cb, str, strlen(str), &match, 1, 0)) {
+            cb_get_kv(match, &i, sizeof(int));
+            result = (param_t)i;
+        }
+    }
+    return result;
+}
+
+param_t findparam_block(const char *s, const struct locale *lang, bool any_locale)
+{
+    param_t p;
+    if (!s || s[0] == '@') {
+        return NOPARAM;
+    }
+    p = findparam(s, lang);
+    if (any_locale && p == NOPARAM) {
+        const struct locale *loc;
+        for (loc = locales; loc; loc = nextlocale(loc)) {
+            if (loc != lang) {
+                p = findparam(s, loc);
+                if (p == P_FACTION || p == P_GAMENAME) {
+                    break;
+                }
+            }
+        }
+    }
+    return p;
+}
+
+bool isparam(const char *s, const struct locale * lang, param_t param)
+{
+    assert(s);
+    assert(param != P_GEBAEUDE);
+    assert(param != P_BUILDING);
+    if (s[0] > '@') {
+        param_t p = findparam(s, lang);
+        return p == param;
+    }
+    return false;
+}
+
+param_t getparam(const struct locale * lang)
+{
+    char token[64];
+    const char *s = gettoken(token, sizeof(token));
+    return s ? findparam(s, lang) : NOPARAM;
+}
+
+static const char * parameter_key(int i)
+{
+    assert(i < MAXPARAMS && i >= 0);
+    return parameters[i];
+}
+
+void init_parameters(struct locale *lang) {
+    init_translations(lang, UT_PARAMS, parameter_key, MAXPARAMS);
+}
diff --git a/src/util/param.h b/src/util/param.h
new file mode 100644
index 000000000..42d34ee57
--- /dev/null
+++ b/src/util/param.h
@@ -0,0 +1,77 @@
+#pragma once
+
+#ifndef H_PARAM_H
+#define H_PARAM_H
+
+#include <stdbool.h>
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+    struct locale;
+
+    typedef enum param_t {
+        P_LOCALE,
+        P_ANY,
+        P_EACH,
+        P_PEASANT,
+        P_BUILDING,
+        P_UNIT,
+        P_PRIVAT,
+        P_BEHIND,
+        P_CONTROL,
+        P_HERBS,
+        P_NOT,
+        P_NEXT,
+        P_FACTION,
+        P_GAMENAME,
+        P_PERSON,
+        P_REGION,
+        P_SHIP,
+        P_MONEY,
+        P_ROAD,
+        P_TEMP,
+        P_FLEE,
+        P_GEBAEUDE,
+        P_GIVE,
+        P_FIGHT,
+        P_TRAVEL,
+        P_GUARD,
+        P_ZAUBER,
+        P_PAUSE,
+        P_VORNE,
+        P_AGGRO,
+        P_CHICKEN,
+        P_LEVEL,
+        P_HELP,
+        P_FOREIGN,
+        P_AURA,
+        P_AFTER,
+        P_BEFORE,
+        P_NUMBER,
+        P_ITEMS,
+        P_POTIONS,
+        P_GROUP,
+        P_FACTIONSTEALTH,
+        P_TREES,
+        P_ALLIANCE,
+        P_AUTO,
+        MAXPARAMS,
+        NOPARAM
+    } param_t;
+
+    extern const char *parameters[MAXPARAMS];
+
+    param_t findparam(const char *s, const struct locale *lang);
+    param_t findparam_block(const char *s, const struct locale *lang, bool any_locale);
+    bool isparam(const char *s, const struct locale * lang, param_t param);
+    param_t getparam(const struct locale *lang);
+
+    void init_parameters(struct locale *lang);
+
+#ifdef __cplusplus
+}
+#endif
+#endif