diff --git a/wmake/etc/lempar.c b/wmake/etc/lempar.c
index e2d0de8cf2114acd84be21f18ab8ed50834692e5..7561d3783db8b789a7ea370e94613d8699f6835d 100644
--- a/wmake/etc/lempar.c
+++ b/wmake/etc/lempar.c
@@ -730,55 +730,6 @@ static YYACTIONTYPE yy_reduce(
   (void)yyLookahead;
   (void)yyLookaheadToken;
   yymsp = yypParser->yytos;
-  assert( yyruleno<(int)(sizeof(yyRuleName)/sizeof(yyRuleName[0])) );
-#ifndef NDEBUG
-  if( yyTraceFILE ){
-    yysize = yyRuleInfoNRhs[yyruleno];
-    if( yysize ){
-      fprintf(yyTraceFILE, "%sReduce %d [%s]%s, pop back to state %d.\n",
-        yyTracePrompt,
-        yyruleno, yyRuleName[yyruleno],
-        yyruleno<YYNRULE_WITH_ACTION ? "" : " without external action",
-        yymsp[yysize].stateno);
-    }else{
-      fprintf(yyTraceFILE, "%sReduce %d [%s]%s.\n",
-        yyTracePrompt, yyruleno, yyRuleName[yyruleno],
-        yyruleno<YYNRULE_WITH_ACTION ? "" : " without external action");
-    }
-  }
-#endif /* NDEBUG */
-
-  /* Check that the stack is large enough to grow by a single entry
-  ** if the RHS of the rule is empty.  This ensures that there is room
-  ** enough on the stack to push the LHS value */
-  if( yyRuleInfoNRhs[yyruleno]==0 ){
-#ifdef YYTRACKMAXSTACKDEPTH
-    if( (int)(yypParser->yytos - yypParser->yystack)>yypParser->yyhwm ){
-      yypParser->yyhwm++;
-      assert( yypParser->yyhwm == (int)(yypParser->yytos - yypParser->yystack));
-    }
-#endif
-#if YYSTACKDEPTH>0
-    if( yypParser->yytos>=yypParser->yystackEnd ){
-      yyStackOverflow(yypParser);
-      /* The call to yyStackOverflow() above pops the stack until it is
-      ** empty, causing the main parser loop to exit.  So the return value
-      ** is never used and does not matter. */
-      return 0;
-    }
-#else
-    if( yypParser->yytos>=&yypParser->yystack[yypParser->yystksz-1] ){
-      if( yyGrowStack(yypParser) ){
-        yyStackOverflow(yypParser);
-        /* The call to yyStackOverflow() above pops the stack until it is
-        ** empty, causing the main parser loop to exit.  So the return value
-        ** is never used and does not matter. */
-        return 0;
-      }
-      yymsp = yypParser->yytos;
-    }
-#endif
-  }
 
   switch( yyruleno ){
   /* Beginning here are the reduction cases.  A typical example
@@ -938,12 +889,56 @@ void Parse(
   }
 #endif
 
-  do{
+  while(1){ /* Exit by "break" */
+    assert( yypParser->yytos>=yypParser->yystack );
     assert( yyact==yypParser->yytos->stateno );
     yyact = yy_find_shift_action((YYCODETYPE)yymajor,yyact);
     if( yyact >= YY_MIN_REDUCE ){
-      yyact = yy_reduce(yypParser,yyact-YY_MIN_REDUCE,yymajor,
-                        yyminor ParseCTX_PARAM);
+      unsigned int yyruleno = yyact - YY_MIN_REDUCE; /* Reduce by this rule */
+      assert( yyruleno<(int)(sizeof(yyRuleName)/sizeof(yyRuleName[0])) );
+#ifndef NDEBUG
+      if( yyTraceFILE ){
+        int yysize = yyRuleInfoNRhs[yyruleno];
+        if( yysize ){
+          fprintf(yyTraceFILE, "%sReduce %d [%s]%s, pop back to state %d.\n",
+            yyTracePrompt,
+            yyruleno, yyRuleName[yyruleno],
+            yyruleno<YYNRULE_WITH_ACTION ? "" : " without external action",
+            yypParser->yytos[yysize].stateno);
+        }else{
+          fprintf(yyTraceFILE, "%sReduce %d [%s]%s.\n",
+            yyTracePrompt, yyruleno, yyRuleName[yyruleno],
+            yyruleno<YYNRULE_WITH_ACTION ? "" : " without external action");
+        }
+      }
+#endif /* NDEBUG */
+
+      /* Check that the stack is large enough to grow by a single entry
+      ** if the RHS of the rule is empty.  This ensures that there is room
+      ** enough on the stack to push the LHS value */
+      if( yyRuleInfoNRhs[yyruleno]==0 ){
+#ifdef YYTRACKMAXSTACKDEPTH
+        if( (int)(yypParser->yytos - yypParser->yystack)>yypParser->yyhwm ){
+          yypParser->yyhwm++;
+          assert( yypParser->yyhwm ==
+                  (int)(yypParser->yytos - yypParser->yystack));
+        }
+#endif
+#if YYSTACKDEPTH>0
+        if( yypParser->yytos>=yypParser->yystackEnd ){
+          yyStackOverflow(yypParser);
+          break;
+        }
+#else
+        if( yypParser->yytos>=&yypParser->yystack[yypParser->yystksz-1] ){
+          if( yyGrowStack(yypParser) ){
+            yyStackOverflow(yypParser);
+            break;
+          }
+        }
+#endif
+      }
+      yyact = yy_reduce(yypParser,yyruleno,yymajor,yyminor ParseCTX_PARAM);
     }else if( yyact <= YY_MAX_SHIFTREDUCE ){
       yy_shift(yypParser,yyact,(YYCODETYPE)yymajor,yyminor);
 #ifndef YYNOERRORRECOVERY
@@ -999,14 +994,13 @@ void Parse(
         yy_destructor(yypParser, (YYCODETYPE)yymajor, &yyminorunion);
         yymajor = YYNOCODE;
       }else{
-        while( yypParser->yytos >= yypParser->yystack
-            && (yyact = yy_find_reduce_action(
-                        yypParser->yytos->stateno,
-                        YYERRORSYMBOL)) > YY_MAX_SHIFTREDUCE
-        ){
+        while( yypParser->yytos > yypParser->yystack ){
+          yyact = yy_find_reduce_action(yypParser->yytos->stateno,
+                                        YYERRORSYMBOL);
+          if( yyact<=YY_MAX_SHIFTREDUCE ) break;
           yy_pop_parser_stack(yypParser);
         }
-        if( yypParser->yytos < yypParser->yystack || yymajor==0 ){
+        if( yypParser->yytos <= yypParser->yystack || yymajor==0 ){
           yy_destructor(yypParser,(YYCODETYPE)yymajor,&yyminorunion);
           yy_parse_failed(yypParser);
 #ifndef YYNOERRORRECOVERY
@@ -1056,7 +1050,7 @@ void Parse(
       break;
 #endif
     }
-  }while( yypParser->yytos>yypParser->yystack );
+  }
 #ifndef NDEBUG
   if( yyTraceFILE ){
     yyStackEntry *i;
diff --git a/wmake/makefiles/apps b/wmake/makefiles/apps
index 1673e8e1dbbcadced97ef304579f026d8bd94b35..fbbb52f43c9e773c44ae77aec93e38bff7f57ca4 100644
--- a/wmake/makefiles/apps
+++ b/wmake/makefiles/apps
@@ -8,8 +8,7 @@
 #     Copyright (C) 2011-2016 OpenFOAM Foundation
 #------------------------------------------------------------------------------
 # License
-#     This file is part of OpenFOAM, licensed under GNU General Public License
-#     <http://www.gnu.org/licenses/>.
+#     This file is part of OpenFOAM, distributed under GPL-3.0-or-later.
 #
 # File
 #     wmake/makefiles/apps
diff --git a/wmake/rules/General/eigen b/wmake/rules/General/eigen
new file mode 100644
index 0000000000000000000000000000000000000000..a47c3286f50d8058b49b3d580e25e141e9826425
--- /dev/null
+++ b/wmake/rules/General/eigen
@@ -0,0 +1,14 @@
+# ----------------------------------------------------------------------------
+# Eigen definitions
+#
+#  0. missing
+#  1. header-only
+# ----------------------------------------------------------------------------
+
+ifneq (,$(EIGEN_INC_DIR))
+    EIGEN_INC := -I$(EIGEN_INC_DIR)
+else
+    EIGEN_INC :=
+endif
+
+# ---------------------------------------------------------------------------
diff --git a/wmake/scripts/dirToString b/wmake/scripts/dirToString
index 55d027e044ffce5f21be0e457fb2e26e4109516e..2ed4ba76192cf851dc9bb84ffb6bcc81ddb7a0b6 100755
--- a/wmake/scripts/dirToString
+++ b/wmake/scripts/dirToString
@@ -9,8 +9,7 @@
 #     Copyright (C) 2019 OpenCFD Ltd.
 #------------------------------------------------------------------------------
 # License
-#     This file is part of OpenFOAM, licensed under GNU General Public License
-#     <http://www.gnu.org/licenses/>.
+#     This file is part of OpenFOAM, distributed under GPL-3.0-or-later.
 #
 # Script
 #     dirToString
diff --git a/wmake/scripts/have_eigen b/wmake/scripts/have_eigen
new file mode 100644
index 0000000000000000000000000000000000000000..a674e31e57ca8f4615cdc6f9c8d69ceb6cb4e375
--- /dev/null
+++ b/wmake/scripts/have_eigen
@@ -0,0 +1,159 @@
+#----------------------------------*-sh-*--------------------------------------
+# =========                 |
+# \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
+#  \\    /   O peration     |
+#   \\  /    A nd           | www.openfoam.com
+#    \\/     M anipulation  |
+#------------------------------------------------------------------------------
+#     Copyright (C) 2021 OpenCFD Ltd.
+#------------------------------------------------------------------------------
+# License
+#     This file is part of OpenFOAM, distributed under GPL-3.0-or-later.
+#
+# Script
+#     have_eigen
+#
+# Description
+#     Detection/setup of EIGEN (Eigen3)
+#
+# Expects
+#     config.sh/eigen
+#
+# Functions provided
+#     have_eigen, no_eigen, echo_eigen, query_eigen, search_eigen
+#
+# Variables set on success
+#     HAVE_EIGEN
+#     EIGEN_INC_DIR
+#
+#------------------------------------------------------------------------------
+. ${WM_PROJECT_DIR:?}/wmake/scripts/sysFunctions    # General system functions
+
+#------------------------------------------------------------------------------
+
+# Reset
+no_eigen()
+{
+    unset HAVE_EIGEN EIGEN_INC_DIR EIGEN_LIB_DIR
+}
+
+
+# Report
+echo_eigen()
+{
+    echo "eigen=${HAVE_EIGEN:-false}"
+    echo "include=\"$EIGEN_INC_DIR\""
+}
+
+
+# Search
+# $1 : prefix (*_ARCH_PATH, system, ...)
+#
+# On success, return 0 and export variables
+# -> HAVE_EIGEN, EIGEN_INC_DIR
+search_eigen()
+{
+    local warn # warn="==> skip eigen"
+    local incName="Eigen/Eigen"
+    local pkgName="eigen3"
+    local sentinel="signature_of_eigen3_matrix_library"
+
+    local prefix="${1:-system}"
+    local header incdir
+
+    # ----------------------------------
+    if isNone "$prefix"
+    then
+        [ -n "$warn" ] && echo "$warn (disabled)"
+        return 1
+    elif hasAbsdir "$prefix"
+    then
+        header=$(findFirstFile "$prefix/include/$incName")
+    elif isSystem "$prefix"
+    then
+        header=$(findSystemInclude -name="eigen3/$incName")
+
+        # No system header, attempt discovery with pkg-config
+        if [ -z "$header" ] && pkg-config --exists "$pkgName" 2>/dev/null
+        then
+            includeDirs=$(pkg-config --cflags-only-I "$pkgName" | sed -e 's/^-[IL]//; s/[ ]-[IL]/ /;')
+            header="${includeDirs% *}/$incName"   # First entry (ie, split on space)
+        fi
+    else
+        unset prefix
+    fi
+    # ----------------------------------
+
+    # Header
+    [ -n "$header" ] || {
+        [ -n "$warn" ] && echo "$warn (no header)"
+        return 2
+    }
+
+    # ----------------------------------
+
+    header="${header%/*}"   # Strip one-level (include/Eigen/...)
+
+    # OK
+    export HAVE_EIGEN=true
+    export EIGEN_INC_DIR="${header%/*}"     # Basename
+}
+
+
+# Output as per search_* function
+have_eigen()
+{
+    local warn # warn="==> skip eigen"
+    local config="config.sh/eigen"
+    local path="$EIGEN_ARCH_PATH"
+    local file
+
+    # Setup - current environment if set
+    if [ -z "$path" ]
+    then
+        if file="$("$WM_PROJECT_DIR"/bin/foamEtcFile "$config")"
+        then
+            . "$file"
+            path="$EIGEN_ARCH_PATH"
+        fi
+    fi
+
+    search_eigen "${path:-system}"
+}
+
+
+# Query settings
+query_eigen()
+{
+    local config="config.sh/eigen"
+    local file
+
+    if file="$("$WM_PROJECT_DIR"/bin/foamEtcFile -mode=o "$config")"
+    then
+        . "$file"
+        _process_query eigen "${EIGEN_ARCH_PATH:-system}"
+    else
+        echo "(no $config)" 1>&2
+        echo "eigen=unknown"
+        _process_query eigen "system"
+    fi
+}
+
+
+#------------------------------------------------------------------------------
+
+# Reset
+no_eigen
+
+# Test/query
+case "$1" in
+-test)
+    have_eigen
+    echo_eigen
+    ;;
+-query)
+    query_eigen
+    ;;
+esac
+
+#------------------------------------------------------------------------------
diff --git a/wmake/scripts/makeDepend b/wmake/scripts/makeDepend
index 1aa1f6f7e7e441936c8bbeacc65eb58a7890517a..711275614da3a10be3d21cca31706ce0f84f41f3 100755
--- a/wmake/scripts/makeDepend
+++ b/wmake/scripts/makeDepend
@@ -9,8 +9,7 @@
 #     Copyright (C) 2018 OpenCFD Ltd.
 #------------------------------------------------------------------------------
 # License
-#     This file is part of OpenFOAM, licensed under GNU General Public License
-#     <http://www.gnu.org/licenses/>.
+#     This file is part of OpenFOAM, distributed under GPL-3.0-or-later.
 #
 # Script
 #     makeDepend
diff --git a/wmake/scripts/makeFiles b/wmake/scripts/makeFiles
index 7fa9c69c3fa4867d49ed47b42a552b002e276d6e..48112401ae92febfa9cd0754ae4d108e48e88a72 100755
--- a/wmake/scripts/makeFiles
+++ b/wmake/scripts/makeFiles
@@ -9,20 +9,7 @@
 #     Copyright (C) 2011-2016 OpenFOAM Foundation
 #------------------------------------------------------------------------------
 # License
-#     This file is part of OpenFOAM.
-#
-#     OpenFOAM is free software: you can redistribute it and/or modify it
-#     under the terms of the GNU General Public License as published by
-#     the Free Software Foundation, either version 3 of the License, or
-#     (at your option) any later version.
-#
-#     OpenFOAM 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 General Public License
-#     for more details.
-#
-#     You should have received a copy of the GNU General Public License
-#     along with OpenFOAM.  If not, see <http://www.gnu.org/licenses/>.
+#     This file is part of OpenFOAM, distributed under GPL-3.0-or-later.
 #
 # Script
 #     makeFiles
diff --git a/wmake/scripts/makeOptions b/wmake/scripts/makeOptions
index 3d27c475f049e9928abd101aa02528535d83e804..36c4eb2ef74a5460f1dea0dac6a7525aef84092f 100755
--- a/wmake/scripts/makeOptions
+++ b/wmake/scripts/makeOptions
@@ -9,20 +9,7 @@
 #     Copyright (C) 2011 OpenFOAM Foundation
 #------------------------------------------------------------------------------
 # License
-#     This file is part of OpenFOAM.
-#
-#     OpenFOAM is free software: you can redistribute it and/or modify it
-#     under the terms of the GNU General Public License as published by
-#     the Free Software Foundation, either version 3 of the License, or
-#     (at your option) any later version.
-#
-#     OpenFOAM 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 General Public License
-#     for more details.
-#
-#     You should have received a copy of the GNU General Public License
-#     along with OpenFOAM.  If not, see <http://www.gnu.org/licenses/>.
+#     This file is part of OpenFOAM, distributed under GPL-3.0-or-later.
 #
 # Script
 #     makeOptions
diff --git a/wmake/scripts/makeParser b/wmake/scripts/makeParser
index da094042ca795bffdfc5504f4d50a6f9e1915368..ee59ded8959bfea1e09b38aabed21935f8ca8569 100755
--- a/wmake/scripts/makeParser
+++ b/wmake/scripts/makeParser
@@ -9,8 +9,7 @@
 #   Copyright (C) 2019 OpenCFD Ltd.
 #-------------------------------------------------------------------------------
 # License
-#     This file is part of OpenFOAM, licensed under GNU General Public License
-#     <http://www.gnu.org/licenses/>.
+#     This file is part of OpenFOAM, distributed under GPL-3.0-or-later.
 #
 # Script
 #     makeParser
@@ -19,9 +18,7 @@
 #     Pregenerate ragel code and/or lemon parser headers
 #
 #------------------------------------------------------------------------------
-usage() {
-    exec 1>&2
-    while [ "$#" -ge 1 ]; do echo "$1"; shift; done
+printHelp() {
     cat<<USAGE
 
 Usage: ${0##*/} [options]
@@ -32,7 +29,9 @@ options:
   -scanner=FILE     Generate ragel scanner code
   -code             Generate parser code, not header
   -header           Generate parser header, not code (default)
+  -grammar          Output grammar tables (if supported)
   -dry-run          Process m4 only (output on stdout)
+  -no-lines         Suppress generation of #line directives
   -no-tmp           Do not retain temporary m4 processed files
   -remove           Remove generated code
   -h, -help         Print the usage
@@ -40,18 +39,19 @@ options:
 Pregenerate ragel code and/or lemon parser headers
 
 USAGE
-    exit 1
+    exit 0 # Clean exit
 }
 
 #------------------------------------------------------------------------------
 # Parse arguments and options
 #------------------------------------------------------------------------------
 
-unset prefix parser scanner optHeader optDryRun optRemoveFile optRemoveTmp
+unset prefix parser scanner optHeader optGrammar optDryRun
+unset optRemoveFile optRemoveTmp optNoLines
 while [ "$#" -gt 0 ]
 do
     case "$1" in
-    (-h | -help*) usage ;;
+    (-h | -help*) printHelp ;;
 
     (-prefix=*)   prefix="${1#*=}" ;;
     (-parser=*)   parser="${1#*=}" ;;
@@ -59,7 +59,9 @@ do
 
     (-code)       optHeader=false ;;
     (-head*)      optHeader=true ;;
+    (-gram*)      optGrammar="-grammar" ;;  # Pass verbatim to wrapper
     (-dry-run)    optDryRun="-dry-run" ;;   # Pass verbatim to wrapper
+    (-no-lines)   optNoLines=true ;;
     (-no-tmp)     optRemoveTmp="-no-tmp" ;; # Pass verbatim to wrapper
     (-remove)     optRemoveFile=true ;;
 
@@ -92,7 +94,7 @@ case "$scanner" in
     elif command -v ragel >/dev/null
     then
         echo "Generating ragel scanner" 1>&2
-        ragel -G2 -o "$output" "$input"
+        ragel -G2 ${optNoLines:+-L} -o "$output" "$input"
     else
         echo "No ragel, leaving scanner intact" 1>&2
     fi
@@ -144,11 +146,13 @@ case "$parser" in
         then
             echo "Generating lemon parser code ($extCode)$message" 1>&2
             "${WM_PROJECT_DIR:?}/wmake/scripts/wrap-lemon" \
-                $optDryRun $optRemoveTmp -e"$extCode" -p -s "$input"
+                $optDryRun $optGrammar $optRemoveTmp \
+                -e"$extCode" -p -s "$input"
         else
             echo "Generating lemon parser header$message" 1>&2
             "${WM_PROJECT_DIR:?}/wmake/scripts/wrap-lemon" \
-                $optDryRun $optRemoveTmp -header -p -s "$input"
+                $optDryRun $optGrammar $optRemoveTmp -header \
+                -p -s "$input"
         fi
     fi
     echo
diff --git a/wmake/scripts/makeTargetDir b/wmake/scripts/makeTargetDir
index 44b778f9ba7fe8d96bb9f5b64bd68771d5cda10f..18ecb22d2f03d7e4509d7d3ab67309effbc3f7df 100755
--- a/wmake/scripts/makeTargetDir
+++ b/wmake/scripts/makeTargetDir
@@ -9,8 +9,7 @@
 #     Copyright (C) 2011 OpenFOAM Foundation
 #------------------------------------------------------------------------------
 # License
-#     This file is part of OpenFOAM, licensed under GNU General Public License
-#     <http://www.gnu.org/licenses/>.
+#     This file is part of OpenFOAM, distributed under GPL-3.0-or-later.
 #
 # Script
 #     makeTargetDir
diff --git a/wmake/scripts/wmakeFilesAndOptions b/wmake/scripts/wmakeFilesAndOptions
index 8b35a52d04addeca245be082a82ee940d4e1f51f..48cf9f103209458831fcf9d441e89405025f117a 100755
--- a/wmake/scripts/wmakeFilesAndOptions
+++ b/wmake/scripts/wmakeFilesAndOptions
@@ -9,20 +9,7 @@
 #     Copyright (C) 2011-2016 OpenFOAM Foundation
 #------------------------------------------------------------------------------
 # License
-#     This file is part of OpenFOAM.
-#
-#     OpenFOAM is free software: you can redistribute it and/or modify it
-#     under the terms of the GNU General Public License as published by
-#     the Free Software Foundation, either version 3 of the License, or
-#     (at your option) any later version.
-#
-#     OpenFOAM 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 General Public License
-#     for more details.
-#
-#     You should have received a copy of the GNU General Public License
-#     along with OpenFOAM.  If not, see <http://www.gnu.org/licenses/>.
+#     This file is part of OpenFOAM, distributed under GPL-3.0-or-later.
 #
 # Script
 #     wmakeFilesAndOptions
diff --git a/wmake/scripts/wmakeWindowsDlOpenLibs b/wmake/scripts/wmakeWindowsDlOpenLibs
index 52b24489f5cf58e5272d5f0a2b001734f6e0bab6..594183c389170660b1aec65e5bc891c44805cd6d 100755
--- a/wmake/scripts/wmakeWindowsDlOpenLibs
+++ b/wmake/scripts/wmakeWindowsDlOpenLibs
@@ -10,20 +10,7 @@
 #     Copyright (C) 2019 OpenCFD Ltd.
 #------------------------------------------------------------------------------
 # License
-#     This file is part of OpenFOAM.
-#
-#     OpenFOAM is free software: you can redistribute it and/or modify it
-#     under the terms of the GNU General Public License as published by
-#     the Free Software Foundation, either version 3 of the License, or
-#     (at your option) any later version.
-#
-#     OpenFOAM 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 General Public License
-#     for more details.
-#
-#     You should have received a copy of the GNU General Public License
-#     along with OpenFOAM.  If not, see <http://www.gnu.org/licenses/>.
+#     This file is part of OpenFOAM, distributed under GPL-3.0-or-later.
 #
 # Script
 #     wmakeWindowsDlOpenLibs
diff --git a/wmake/scripts/wrap-bison b/wmake/scripts/wrap-bison
index c158e8acbe41c2170ccc6ed290dd3698e4cafa2d..f7484d2788c68e43ffaae68dc382d524cb0fa786 100755
--- a/wmake/scripts/wrap-bison
+++ b/wmake/scripts/wrap-bison
@@ -6,11 +6,10 @@
 #   \\  /    A nd           | www.openfoam.com
 #    \\/     M anipulation  |
 #-------------------------------------------------------------------------------
-#   Copyright (C) 2019 OpenCFD Ltd.
+#   Copyright (C) 2019-2021 OpenCFD Ltd.
 #-------------------------------------------------------------------------------
 # License
-#     This file is part of OpenFOAM, licensed under GNU General Public License
-#     <http://www.gnu.org/licenses/>.
+#     This file is part of OpenFOAM, distributed under GPL-3.0-or-later.
 #
 # Script
 #     wrap-bison
@@ -53,15 +52,14 @@
 # Note
 #     General idea lifted from swak
 #------------------------------------------------------------------------------
-usage() {
-    exec 1>&2
-    while [ "$#" -ge 1 ]; do echo "$1"; shift; done
+printHelp() {
     cat<<USAGE
 
 Usage: ${0##*/} [options] [bison args/options]
 
 options:
   -dry-run          Process m4 only (output on stdout)
+  -grammar          Output grammar tables (ignored)
   -no-tmp           Do not retain temporary m4 processed files
   -output=NAME      Request renaming actions
   -h, -help         Print the usage
@@ -69,7 +67,7 @@ options:
 A bison wrapper with renaming of skeleton files
 
 USAGE
-    exit 1
+    exit 0  # A clean exit
 }
 
 # File extensions used (may need adjustment)
@@ -81,13 +79,14 @@ extHead="hh"
 #------------------------------------------------------------------------------
 
 # wrap-bison -output=...
-unset outputFile optDryRun optRemoveTmp m4Flags
+unset outputFile optDryRun optGrammar optRemoveTmp m4Flags
 while [ "$#" -gt 0 ]
 do
     case "$1" in
     (-h | -help*) usage ;;
 
     (-dry-run)      optDryRun=true ;;
+    (-gram*)        optGrammar=true ;;  # currently ignored
     (-no-tmp)       optRemoveTmp=true ;;
     (-output=*)     outputFile="${1#*=}" ;;
 
diff --git a/wmake/scripts/wrap-lemon b/wmake/scripts/wrap-lemon
index f9080d95ce0fe81300a5bdf801db3a7f151ec163..c0e82f6f3ba424b6a3a4f9ccf89fcf5bed67c7f4 100755
--- a/wmake/scripts/wrap-lemon
+++ b/wmake/scripts/wrap-lemon
@@ -6,7 +6,7 @@
 #   \\  /    A nd           | www.openfoam.com
 #    \\/     M anipulation  |
 #-------------------------------------------------------------------------------
-#   Copyright (C) 2019-2020 OpenCFD Ltd.
+#   Copyright (C) 2019-2021 OpenCFD Ltd.
 #-------------------------------------------------------------------------------
 # License
 #     This file is part of OpenFOAM, distributed under GPL-3.0-or-later.
@@ -34,12 +34,10 @@ binDir="${WMAKE_BIN:-$WM_PROJECT_DIR/platforms/tools/$WM_ARCH$WM_COMPILER}"
 etcDir="${WM_DIR:-$WM_PROJECT_DIR/wmake}/etc"
 
 # Executable and skeleton locations
-lemon="$binDir/lemon"
+lemon="${binDir}/lemon"
 skel="-T${etcDir}/lempar.c"
 
-usage() {
-    exec 1>&2
-    while [ "$#" -ge 1 ]; do echo "$1"; shift; done
+printHelp() {
     cat<<USAGE
 
 Usage: ${0##*/} [options] [lemon args/options]
@@ -47,6 +45,7 @@ Usage: ${0##*/} [options] [lemon args/options]
 options:
   -header           Generate header only, suppressing other output
   -dry-run          Process m4 only (output on stdout)
+  -grammar          Output grammar tables (stdout)
   -no-tmp           Do not retain temporary m4 processed files
   -h, -help         Print the usage
 
@@ -56,7 +55,7 @@ the m4(1) macro processor and lemon will be called with 'm4' as a macro
 definition, which can be used in conditions (%ifdef m4, %ifndef m4)
 
 USAGE
-    exit 1
+    exit 0  # Clean exit
 }
 
 #------------------------------------------------------------------------------
@@ -64,14 +63,15 @@ USAGE
 #------------------------------------------------------------------------------
 
 # Eg, wrap-lemon -header
-unset optHeader optDryRun optRemoveTmp m4Flags
+unset optDryRun optHeader optGrammar optRemoveTmp m4Flags
 while [ "$#" -gt 0 ]
 do
     case "$1" in
-    (-h | -help*)   usage ;;
+    (-h | -help*)   printHelp ;;
 
-    (-head*)        optHeader=true ;;
     (-dry-run)      optDryRun=true ;;
+    (-head*)        optHeader=true ;;
+    (-gram*)        optGrammar=true ;;
     (-no-tmp)       optRemoveTmp=true ;;
 
     (*) break ;;
@@ -163,6 +163,12 @@ case "$parser" in
     ;;
 esac
 
+if [ -n "$optGrammar" ]
+then
+    parserFlags="${parserFlags}${parserFlags:+ }-g"
+fi
+
+
 exitCode=0  # No failures
 
 #------------------------------------------------------------------------------
@@ -188,6 +194,8 @@ unset tmpFile tmpDir
 
 if [ -n "$optHeader" ]
 then
+    ## echo "${0##*/} : generate header" 1>&2
+
     # Drop last argument (the parser input file)
     set -- "${@:1:${#}-1}"
 
@@ -196,8 +204,7 @@ then
     rm -rf "$tmpDir" 2>/dev/null
     mkdir "$tmpDir" 2>/dev/null
 
-    # We may want this:
-    # trap 'rm -f $tmpDir 2>/dev/null; exit $exitCode' EXIT TERM INT
+    trap 'rm -rf $tmpDir; exit $exitCode' EXIT TERM INT
 
     if [ "$usingM4" = true ]
     then
@@ -236,10 +243,10 @@ then
         done
     fi
 
-    rm -rf "$tmpDir" 2>/dev/null
-
 elif [ "$usingM4" = true ]
 then
+    ## echo "${0##*/} : generate code (with m4 filtering)" 1>&2
+
     # Drop last argument (the parser input file)
     set -- "${@:1:${#}-1}"
 
@@ -252,8 +259,10 @@ then
     fi
     tmpFile="${tmpFile%.*}$extParser"   # Eg, from .lyy-m4 -> .lyy
 
-    # We may want this:
-    # trap 'rm -f $tmpFile 2>/dev/null; exit $exitCode' EXIT TERM INT
+    if [ -n "$optRemoveTmp" ]
+    then
+        trap 'rm -f $tmpFile; exit $exitCode' EXIT TERM INT
+    fi
 
     if m4 $m4Flags "$parser" > "$tmpFile" && [ -f "$tmpFile" ]
     then
@@ -264,16 +273,16 @@ then
         exitCode=1
     fi
 
-    if [ -n "$optRemoveTmp" ]
+    if [ -z "$optRemoveTmp" ]
     then
-        rm -f "$tmpFile" 2>/dev/null
-    else
+        echo 2>/dev/null
         echo "Retaining intermediate: $tmpFile" 2>/dev/null
     fi
 
 else
 
     # No special handling
+    ## echo "${0##*/} : generate code" 1>&2
 
     "$lemon" "$skel" "$@"
     exitCode=$?
diff --git a/wmake/src/lemon.c b/wmake/src/lemon.c
index 216972677de738db011971f7086595e830434b0a..52fb402aeab66e133a19899442554549b1475b77 100644
--- a/wmake/src/lemon.c
+++ b/wmake/src/lemon.c
@@ -1,7 +1,9 @@
-/*
- * https://www.sqlite.org/src/artifact/70eedc31
- * Artifact 70eedc31614a58fe31a71025c17ebd1502a6ce9cfef0ed5e33acb0b5b737b291:
- * File tool/lemon.c part of check-in [4591ee03] at 2020-09-21
+/* OPENFOAM note
+ *
+ * https://sqlite.org/src/raw/
+ * https://www.sqlite.org/src/artifact/25888183
+ * Artifact 258881835bd5bccd0c74fb110fe54244ff18e8e7ef3d949cbdab7187f02132bb:
+ * File tool/lemon.c part of check-in [f2f279b2]] at 2021-10-04
  */
 /*
 ** This file contains all sources (including headers) to the LEMON
@@ -406,7 +408,7 @@ struct lemon {
   struct symbol *errsym;   /* The error symbol */
   struct symbol *wildcard; /* Token that matches anything */
   char *name;              /* Name of the generated parser */
-  char *arg;               /* Declaration of the 3th argument to parser */
+  char *arg;               /* Declaration of the 3rd argument to parser */
   char *ctx;               /* Declaration of 2nd argument to constructor */
   char *tokentype;         /* Type of terminal symbols in the parser stack */
   char *vartype;           /* The default type of non-terminal symbols */
@@ -923,8 +925,11 @@ void FindStates(struct lemon *lemp)
       lemp->errorcnt++;
       sp = lemp->startRule->lhs;
     }
-  }else{
+  }else if( lemp->startRule ){
     sp = lemp->startRule->lhs;
+  }else{
+    ErrorMsg(lemp->filename,0,"Internal error - no start rule\n");
+    exit(1);
   }
 
   /* Make sure the start symbol doesn't occur on the right-hand side of
@@ -1033,7 +1038,7 @@ PRIVATE void buildshifts(struct lemon *lemp, struct state *stp)
   struct symbol *bsp;  /* Symbol following the dot in configuration "bcfp" */
   struct state *newstp; /* A pointer to a successor state */
 
-  /* Each configuration becomes complete after it contibutes to a successor
+  /* Each configuration becomes complete after it contributes to a successor
   ** state.  Initially, all configurations are incomplete */
   for(cfp=stp->cfp; cfp; cfp=cfp->next) cfp->status = INCOMPLETE;
 
@@ -1089,7 +1094,7 @@ void FindLinks(struct lemon *lemp)
   ** which the link is attached. */
   for(i=0; i<lemp->nstate; i++){
     stp = lemp->sorted[i];
-    for(cfp=stp->cfp; cfp; cfp=cfp->next){
+    for(cfp=stp?stp->cfp:0; cfp; cfp=cfp->next){
       cfp->stp = stp;
     }
   }
@@ -1098,7 +1103,7 @@ void FindLinks(struct lemon *lemp)
   ** links are used in the follow-set computation. */
   for(i=0; i<lemp->nstate; i++){
     stp = lemp->sorted[i];
-    for(cfp=stp->cfp; cfp; cfp=cfp->next){
+    for(cfp=stp?stp->cfp:0; cfp; cfp=cfp->next){
       for(plp=cfp->bplp; plp; plp=plp->next){
         other = plp->cfp;
         Plink_add(&other->fplp,cfp);
@@ -1121,6 +1126,7 @@ void FindFollowSets(struct lemon *lemp)
   int change;
 
   for(i=0; i<lemp->nstate; i++){
+    assert( lemp->sorted[i]!=0 );
     for(cfp=lemp->sorted[i]->cfp; cfp; cfp=cfp->next){
       cfp->status = INCOMPLETE;
     }
@@ -1129,6 +1135,7 @@ void FindFollowSets(struct lemon *lemp)
   do{
     progress = 0;
     for(i=0; i<lemp->nstate; i++){
+      assert( lemp->sorted[i]!=0 );
       for(cfp=lemp->sorted[i]->cfp; cfp; cfp=cfp->next){
         if( cfp->status==COMPLETE ) continue;
         for(plp=cfp->fplp; plp; plp=plp->next){
@@ -1178,7 +1185,14 @@ void FindActions(struct lemon *lemp)
   /* Add the accepting token */
   if( lemp->start ){
     sp = Symbol_find(lemp->start);
-    if( sp==0 ) sp = lemp->startRule->lhs;
+    if( sp==0 ){
+      if( lemp->startRule==0 ){
+        fprintf(stderr, "internal error on source line %d: no start rule\n",
+                __LINE__);
+        exit(1);
+      }
+      sp = lemp->startRule->lhs;
+    }
   }else{
     sp = lemp->startRule->lhs;
   }
@@ -1305,21 +1319,7 @@ static struct config **basisend = 0;     /* End of list of basis configs */
 
 /* Return a pointer to a new configuration */
 PRIVATE struct config *newconfig(void){
-  struct config *newcfg;
-  if( freelist==0 ){
-    int i;
-    int amt = 3;
-    freelist = (struct config *)calloc( amt, sizeof(struct config) );
-    if( freelist==0 ){
-      fprintf(stderr,"Unable to allocate memory for a new configuration.");
-      exit(1);
-    }
-    for(i=0; i<amt-1; i++) freelist[i].next = &freelist[i+1];
-    freelist[amt-1].next = 0;
-  }
-  newcfg = freelist;
-  freelist = freelist->next;
-  return newcfg;
+  return (struct config*)calloc(1, sizeof(struct config));
 }
 
 /* The configuration "old" is no longer used */
@@ -1549,7 +1549,7 @@ static void handle_D_option(char *z){
   *z = 0;
 }
 
-/* Remember the name of the output directory
+/* Rember the name of the output directory
 */
 static char *outputDir = NULL;
 static void handle_d_option(char *z){
@@ -1912,7 +1912,7 @@ static char *merge(
 **
 ** Return Value:
 **   A pointer to the head of a sorted list containing the elements
-**   orginally in list.
+**   originally in list.
 **
 ** Side effects:
 **   The "next" pointers for elements in list are changed.
@@ -1957,8 +1957,12 @@ static FILE *errstream;
 static void errline(int n, int k, FILE *err)
 {
   int spcnt, i;
-  if( g_argv[0] ) fprintf(err,"%s",g_argv[0]);
-  spcnt = lemonStrlen(g_argv[0]) + 1;
+  if( g_argv[0] ){
+    fprintf(err,"%s",g_argv[0]);
+    spcnt = lemonStrlen(g_argv[0]) + 1;
+  }else{
+    spcnt = 0;
+  }
   for(i=1; i<n && g_argv[i]; i++){
     fprintf(err," %s",g_argv[i]);
     spcnt += lemonStrlen(g_argv[i])+1;
@@ -2739,7 +2743,7 @@ static void parseonetoken(struct pstate *psp)
       ** in order to control their assigned integer number.  The number for
       ** each token is assigned when it is first seen.  So by including
       **
-      **     %token ONE TWO THREE
+      **     %token ONE TWO THREE.
       **
       ** early in the grammar file, that assigns small consecutive values
       ** to each of the tokens ONE TWO and THREE.
@@ -3544,7 +3548,7 @@ void ReportOutput(struct lemon *lemp)
 }
 
 /* Search for the file "name" which is in the same directory as
-** the exacutable */
+** the executable */
 PRIVATE char *pathsearch(char *argv0, char *name, int modemask)
 {
   const char *pathlist;
@@ -3602,7 +3606,9 @@ PRIVATE int compute_action(struct lemon *lemp, struct action *ap)
       /* Since a SHIFT is inherient after a prior REDUCE, convert any
       ** SHIFTREDUCE action with a nonterminal on the LHS into a simple
       ** REDUCE action: */
-      if( ap->sp->index>=lemp->nterminal ){
+      if( ap->sp->index>=lemp->nterminal
+       && (lemp->errsym==0 || ap->sp->index!=lemp->errsym->index)
+      ){
         act = lemp->minReduce + ap->x.rp->iRule;
       }else{
         act = lemp->minShiftReduce + ap->x.rp->iRule;
@@ -3899,7 +3905,7 @@ PRIVATE int translate_code(struct lemon *lemp, struct rule *rp){
     lhsdirect = 1;
   }else if( rp->rhsalias[0]==0 ){
     /* The left-most RHS symbol has no value.  LHS direct is ok.  But
-    ** we have to call the distructor on the RHS symbol first. */
+    ** we have to call the destructor on the RHS symbol first. */
     lhsdirect = 1;
     if( has_destructor(rp->rhs[0],lemp) ){
       append_str(0,0,0,0);
@@ -4121,7 +4127,7 @@ void print_stack_union(
   int *plineno,               /* Pointer to the line number */
   int mhflag                  /* True if generating makeheaders output */
 ){
-  int lineno = *plineno;    /* The line number of the output */
+  int lineno;               /* The line number of the output */
   char **types;             /* A hash table of datatypes */
   int arraysize;            /* Size of the "types" array */
   int maxdtlength;          /* Maximum length of any ".datatype" field. */
@@ -4883,7 +4889,7 @@ void ReportTable(
   ** yyRuleInfoNRhs[].
   **
   ** Note: This code depends on the fact that rules are number
-  ** sequentually beginning with 0.
+  ** sequentially beginning with 0.
   */
   for(i=0, rp=lemp->rule; rp; rp=rp->next, i++){
     fprintf(out,"  %4d,  /* (%d) ", rp->lhs->index, i);
@@ -5371,7 +5377,8 @@ int Strsafe_insert(const char *data)
       newnp->from = &(array.ht[h]);
       array.ht[h] = newnp;
     }
-    free(x1a->tbl);
+    /* free(x1a->tbl); // This program was originally for 16-bit machines.
+    ** Don't worry about freeing memory on modern platforms. */
     *x1a = array;
   }
   /* Insert the new data */
@@ -5539,7 +5546,9 @@ int Symbol_insert(struct symbol *data, const char *key)
       newnp->from = &(array.ht[h]);
       array.ht[h] = newnp;
     }
-    free(x2a->tbl);
+    /* free(x2a->tbl); // This program was originally written for 16-bit
+    ** machines.  Don't worry about freeing this trivial amount of memory
+    ** on modern platforms.  Just leak it. */
     *x2a = array;
   }
   /* Insert the new data */
@@ -5875,7 +5884,9 @@ int Configtable_insert(struct config *data)
       newnp->from = &(array.ht[h]);
       array.ht[h] = newnp;
     }
-    free(x4a->tbl);
+    /* free(x4a->tbl); // This code was originall written for 16-bit machines.
+    ** on modern machines, don't worry about freeing this trival amount of
+    ** memory. */
     *x4a = array;
   }
   /* Insert the new data */
diff --git a/wmake/src/lemon.help.txt b/wmake/src/lemon.help.txt
new file mode 100644
index 0000000000000000000000000000000000000000..cf5ca2895ce0644810ed4e0630137c5bb743f7dd
--- /dev/null
+++ b/wmake/src/lemon.help.txt
@@ -0,0 +1,41 @@
+# Snippets for documentation
+
+
+3.1 Command-line options:
+
+* -eextension
+
+  Output code extension, the default is 'c'.
+  Changing this will not change the type of code generated (it will
+  still be C) but it does allow triggering of different make rules
+  or diffferent compiler types.
+
+
+3.2.2  Interface Summary
+
+Notes:
+
+* Use the %name directive to change the "Parse" prefix names of the
+  procedures in the interface.
+
+* Use the %static directive to change the interface type defined by
+  YYFUNCAPI to file `static` linkage. This can be useful if the entire
+  parser code is to be locally wrapped inside of a different caller.
+
+
+
+4.4  Special directives
+
+* %static
+
+
+
+4.4.xxx The %static directive
+
+By default, the functions generated by Lemon are exposed as globally
+visible symbols. You can change this by specifying the %static
+directive.
+
+This places parser routines in a static (ie, file-local) scope so that
+they are not visible outside of the compilation unit. The parser
+routines will then be wrapped with some other type of mechanism.
diff --git a/wmake/wclean b/wmake/wclean
index ca2fe7f81c05a840f5f670c778b7a3d808fec7fb..362bff0e084603eda5f6ad929c60f7a267bd6c91 100755
--- a/wmake/wclean
+++ b/wmake/wclean
@@ -10,20 +10,7 @@
 #     Copyright (C) 2017-2020 OpenCFD Ltd.
 #------------------------------------------------------------------------------
 # License
-#     This file is part of OpenFOAM.
-#
-#     OpenFOAM is free software: you can redistribute it and/or modify it
-#     under the terms of the GNU General Public License as published by
-#     the Free Software Foundation, either version 3 of the License, or
-#     (at your option) any later version.
-#
-#     OpenFOAM 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 General Public License
-#     for more details.
-#
-#     You should have received a copy of the GNU General Public License
-#     along with OpenFOAM.  If not, see <http://www.gnu.org/licenses/>.
+#     This file is part of OpenFOAM, distributed under GPL-3.0-or-later.
 #
 # Script
 #     wclean
diff --git a/wmake/wcleanLnIncludeAll b/wmake/wcleanLnIncludeAll
index 40b05d48ebe26f12cdd32c690b73bf211a0c74b2..e9e2be271c6f039cc53c7e85c7689fe06a49cb44 100755
--- a/wmake/wcleanLnIncludeAll
+++ b/wmake/wcleanLnIncludeAll
@@ -9,20 +9,7 @@
 #     Copyright (C) 2011-2016 OpenFOAM Foundation
 #------------------------------------------------------------------------------
 # License
-#     This file is part of OpenFOAM.
-#
-#     OpenFOAM is free software: you can redistribute it and/or modify it
-#     under the terms of the GNU General Public License as published by
-#     the Free Software Foundation, either version 3 of the License, or
-#     (at your option) any later version.
-#
-#     OpenFOAM 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 General Public License
-#     for more details.
-#
-#     You should have received a copy of the GNU General Public License
-#     along with OpenFOAM.  If not, see <http://www.gnu.org/licenses/>.
+#     This file is part of OpenFOAM, distributed under GPL-3.0-or-later.
 #
 # Script
 #     wcleanLnIncludeAll
diff --git a/wmake/wdep b/wmake/wdep
index 1680c5d48ca1462b8c5b6b5aebc210476af4e11e..6319c8f92ec7392634c424909c720ee7e8f06050 100755
--- a/wmake/wdep
+++ b/wmake/wdep
@@ -10,20 +10,7 @@
 #     Copyright (C) 2017 OpenCFD Ltd.
 #------------------------------------------------------------------------------
 # License
-#     This file is part of OpenFOAM.
-#
-#     OpenFOAM is free software: you can redistribute it and/or modify it
-#     under the terms of the GNU General Public License as published by
-#     the Free Software Foundation, either version 3 of the License, or
-#     (at your option) any later version.
-#
-#     OpenFOAM 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 General Public License
-#     for more details.
-#
-#     You should have received a copy of the GNU General Public License
-#     along with OpenFOAM.  If not, see <http://www.gnu.org/licenses/>.
+#     This file is part of OpenFOAM, distributed under GPL-3.0-or-later.
 #
 # Script
 #     wdep
@@ -39,7 +26,7 @@
 #
 #------------------------------------------------------------------------------
 Script=${0##*/}             # Use 'Script' for error messages in wmakeFunctions
-. ${0%/*}/scripts/wmakeFunctions        # Source wmake functions
+. "${0%/*}"/scripts/wmakeFunctions      # Source wmake functions
 
 usage() {
     exec 1>&2
@@ -84,7 +71,7 @@ fi
 # Check environment variables
 checkEnv
 
-sourceFile=$1
+sourceFile="$1"
 
 #------------------------------------------------------------------------------
 # Check <file> is in the current directory,
diff --git a/wmake/wmake b/wmake/wmake
index abb07294ed59c1ee79e079c2541f12d7bfbdb7c4..7410841500d81fad05c1f046aa3020b5db94985a 100755
--- a/wmake/wmake
+++ b/wmake/wmake
@@ -10,20 +10,7 @@
 #     Copyright (C) 2017-2021 OpenCFD Ltd.
 #------------------------------------------------------------------------------
 # License
-#     This file is part of OpenFOAM.
-#
-#     OpenFOAM is free software: you can redistribute it and/or modify it
-#     under the terms of the GNU General Public License as published by
-#     the Free Software Foundation, either version 3 of the License, or
-#     (at your option) any later version.
-#
-#     OpenFOAM 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 General Public License
-#     for more details.
-#
-#     You should have received a copy of the GNU General Public License
-#     along with OpenFOAM.  If not, see <http://www.gnu.org/licenses/>.
+#     This file is part of OpenFOAM, distributed under GPL-3.0-or-later.
 #
 # Script
 #     wmake
diff --git a/wmake/wmakeCollect b/wmake/wmakeCollect
index 392a3fc290777b88f3529456fcda09d7f97a34ce..411e209315b579b66407083979d2de745b94656e 100755
--- a/wmake/wmakeCollect
+++ b/wmake/wmakeCollect
@@ -9,20 +9,7 @@
 #     Copyright (C) 2016 OpenFOAM Foundation
 #------------------------------------------------------------------------------
 # License
-#     This file is part of OpenFOAM.
-#
-#     OpenFOAM is free software: you can redistribute it and/or modify it
-#     under the terms of the GNU General Public License as published by
-#     the Free Software Foundation, either version 3 of the License, or
-#     (at your option) any later version.
-#
-#     OpenFOAM 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 General Public License
-#     for more details.
-#
-#     You should have received a copy of the GNU General Public License
-#     along with OpenFOAM.  If not, see <http://www.gnu.org/licenses/>.
+#     This file is part of OpenFOAM, distributed under GPL-3.0-or-later.
 #
 # Script
 #     wmakeCollect
@@ -95,7 +82,7 @@ done
 
 if [ -z "$WM_COLLECT_DIR" ]
 then
-    echo "$Script error: WM_COLLECT_DIR not set"
+    echo "$Script error: WM_COLLECT_DIR not set" 1>&2
     exit 1
 fi
 
@@ -143,7 +130,7 @@ then
     echo -e "\t$E cd $PWD && \\" >> $file
     echo -e "\t${@:1:($#-1)} $objectFile" >> $file
     echo >> $file
-elif [ -d $WM_COLLECT_DIR ]
+elif [ -d "$WM_COLLECT_DIR" ]
 then
     # Collect all the makefiles into a single makefiles for this build
     (cd $WM_COLLECT_DIR && ls -1rt | xargs cat > $makefile)
diff --git a/wmake/wmakeLnIncludeAll b/wmake/wmakeLnIncludeAll
index 31e5480b4d3e7455f9a3bf06f921ca9127cc25d2..310daf243bdd0065b63969d0999df595464332d7 100755
--- a/wmake/wmakeLnIncludeAll
+++ b/wmake/wmakeLnIncludeAll
@@ -10,20 +10,7 @@
 #     Copyright (C) 2018-2020 OpenCFD Ltd.
 #------------------------------------------------------------------------------
 # License
-#     This file is part of OpenFOAM.
-#
-#     OpenFOAM is free software: you can redistribute it and/or modify it
-#     under the terms of the GNU General Public License as published by
-#     the Free Software Foundation, either version 3 of the License, or
-#     (at your option) any later version.
-#
-#     OpenFOAM 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 General Public License
-#     for more details.
-#
-#     You should have received a copy of the GNU General Public License
-#     along with OpenFOAM.  If not, see <http://www.gnu.org/licenses/>.
+#     This file is part of OpenFOAM, distributed under GPL-3.0-or-later.
 #
 # Script
 #     wmakeLnIncludeAll
diff --git a/wmake/wrmdep b/wmake/wrmdep
index 7137af47294ffe61649939121889e16ea72860d1..ffd993657c8471f38609f080a05f11c4276fa029 100755
--- a/wmake/wrmdep
+++ b/wmake/wrmdep
@@ -10,22 +10,10 @@
 #     Copyright (C) 2017-2019 OpenCFD Ltd.
 #------------------------------------------------------------------------------
 # License
-#     This file is part of OpenFOAM.
+#     This file is part of OpenFOAM, distributed under GPL-3.0-or-later.
 #
-#     OpenFOAM is free software: you can redistribute it and/or modify it
-#     under the terms of the GNU General Public License as published by
-#     the Free Software Foundation, either version 3 of the License, or
-#     (at your option) any later version.
-#
-#     OpenFOAM 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 General Public License
-#     for more details.
-#
-#     You should have received a copy of the GNU General Public License
-#     along with OpenFOAM.  If not, see <http://www.gnu.org/licenses/>.
-#
-# Script wrmdep
+# Script
+#     wrmdep
 #
 # Usage
 #     wrmdep [-a | -all | all] [file1 [..fileN]]
@@ -180,7 +168,7 @@ oldFolders)
 
         find "$objectsDir" -name '*.dep' -type f -print | while read depFile
         do
-            sourceFile=$(depToSource "$depFile")
+            sourceFile="$(depToSource "$depFile")"
 
             # Check C++ or Flex source file exists
             if [ ! -r "$sourceFile" ]
diff --git a/wmake/wrmo b/wmake/wrmo
index 93182bbb1b32177624403d1a5e65c981d81e9443..0ce4bf548b112e179e6d606975557ed3fee93631 100755
--- a/wmake/wrmo
+++ b/wmake/wrmo
@@ -10,20 +10,7 @@
 #     Copyright (C) 2017-2019 OpenCFD Ltd.
 #------------------------------------------------------------------------------
 # License
-#     This file is part of OpenFOAM.
-#
-#     OpenFOAM is free software: you can redistribute it and/or modify it
-#     under the terms of the GNU General Public License as published by
-#     the Free Software Foundation, either version 3 of the License, or
-#     (at your option) any later version.
-#
-#     OpenFOAM 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 General Public License
-#     for more details.
-#
-#     You should have received a copy of the GNU General Public License
-#     along with OpenFOAM.  If not, see <http://www.gnu.org/licenses/>.
+#     This file is part of OpenFOAM, distributed under GPL-3.0-or-later.
 #
 # Script
 #     wrmo