On Fri, Jul 17, 2020 at 12:07:53PM -0000, GitLab Bridge on behalf of prarit 
wrote:
> From: Prarit Bhargava <[email protected]>
> 
> evaluate_configs is a tool that verifies the CONFIG setting hierarchy for
> the kernel.  It can display settings for a specific CONFIG, find and
> remove extra CONFIG files and synchronize the CONFIG settings between
> the common, ark, and fedora directories.
> 
> For example, to view a config,
> 
> [prarit@prarit configs]$ ./evaluate_configs -p priority.rhel -c 
> CONFIG_HEADER_TEST
> CONFIG_HEADER_TEST
> legend                         g  ga1  ga2  d  da1  da2
> common-x86_64                  y  -    -    -  X    -
> common-ppc64le                 y  -    X    -  -    X
> common-s390x                   y  -    X    -  -    X
> common-s390x-zfcpdump          y  -    -    X  X    X
> common-aarch64                 y  -    -    -  X    -
> ark-x86_64                     y  -    -    -  X    -
> ark-ppc64le                    y  -    X    -  -    X
> ark-s390x                      y  -    X    -  -    X
> ark-s390x-zfcpdump             y  -    -    X  X    X
> ark-aarch64                    y  -    -    -  X    -
> pending-common-x86_64          -  -    -    -  X    -
> pending-common-ppc64le         -  -    X    -  -    X
> pending-common-s390x           -  -    X    -  -    X
> pending-common-s390x-zfcpdump  -  -    -    X  X    X
> pending-common-aarch64         -  -    -    -  X    -
> 
> The legend row, shows the subdirectory entries.  These can be mapped
> back to the priority.rhel entries, for example, for x86_64
> 
> x86_64=generic:generic-x86:generic-x86-x86_64
> x86_64-debug=generic:generic-x86:generic-x86-x86_64:debug:debug-x86-x86_64
> 
> are combined into one entry for x86_64 where
> 
> g maps to "generic"
> ga1 maps to "generic-x86"
> ga2 maps to "generic-x86-x86-64"
> d maps to "debug"
> da1 maps to nothing (more on this below)
> da2 maps to debug-x86-x86_64
> 
> The left hand column indicates the directory and config-variant.  For
> example, ark-s390x-zfcpdump is the s390x-zfcpdump variant and the
> row beside it shows the config settings in the ark directory.
> 
> The data contained in the output can have 5 values:
> 
>         y = CONFIG is set to 'y'
>         m = CONFIG is set to 'm'
>         n = CONFIG is set to 'is not set'
>         - = CONFIG file does not exist
>         X = CONFIG file entry is not in priority file
> 
> As can be seen above in the CONFIG_HEADER_TEST output, da1 is not present
> in the priority.rhel file and is marked with an 'X'.
> 
> The -f option can be used to evaluate all the CONFIGs by executing, for
> example
> 
> |# evaluate_configs -p priority.rhel -f
> 
> or a single CONFIG
> 
> |# evaluate_configs -p priority.rhel -f -c CONFIG_HEADER_TEST
> 
> and similarily the common, ark and fedora CONFIGs can be verified by
> executing
> 
> evaluate_configs -j
> 
> or
> 
> evaluate_configs -j -c CONFIG_HEADER_TEST
> 
> The two CONFIG patches in this patchset are runs of
> 
> evaluate_configs -p priority.rhel -f
> evaluate_configs -p priority.fedora -f
> 
> and
> 
> evaluate_configs -j
> 
> v2: Documentation cleanup (herton)
> 
> Signed-off-by: Prarit Bhargava <[email protected]>
> ---
>  redhat/configs/README.evaluate_configs |  134 +++
>  redhat/configs/evaluate_configs        | 1278 +++++++++++++++---------
>  redhat/configs/priority.common         |   28 +
>  redhat/configs/priority.fedora         |   16 +-
>  redhat/configs/priority.rhel           |   16 +-
>  5 files changed, 1015 insertions(+), 457 deletions(-)
>  create mode 100644 redhat/configs/README.evaluate_configs
>  create mode 100644 redhat/configs/priority.common
> 
> diff --git a/redhat/configs/README.evaluate_configs 
> b/redhat/configs/README.evaluate_configs
> new file mode 100644
> index 000000000000..6d53e5d993e1
> --- /dev/null
> +++ b/redhat/configs/README.evaluate_configs
> @@ -0,0 +1,134 @@
> +evaluate_configs is a tool that can verify the settings of kernel
> +CONFIGs in the redhat/configs directory.  The data for evaluate_configs
> +is a combination of the redhat/configs files and the priority files.
> +
> +Introduction to Basic Output
> +============================
> +
> +This command demonstrates how to display information about the
> +CONFIG_HEADER_TEST option for RHEL.
> +
> +[prarit@prarit configs]$ ./evaluate_configs -p priority.rhel -c 
> CONFIG_HEADER_TEST
> +CONFIG_HEADER_TEST
> +legend                         g  ga1  ga2  d  da1  da2
> +common-x86_64                  y  -    -    -  X    -
> +common-ppc64le                 y  -    X    -  -    X
> +common-s390x                   y  -    X    -  -    X
> +common-s390x-zfcpdump          y  -    -    X  X    X
> +common-aarch64                 y  -    -    -  X    -
> +ark-x86_64                     y  -    -    -  X    -
> +ark-ppc64le                    y  -    X    -  -    X
> +ark-s390x                      y  -    X    -  -    X
> +ark-s390x-zfcpdump             y  -    -    X  X    X
> +ark-aarch64                    y  -    -    -  X    -
> +pending-common-x86_64          -  -    -    -  X    -
> +pending-common-ppc64le         -  -    X    -  -    X
> +pending-common-s390x           -  -    X    -  -    X
> +pending-common-s390x-zfcpdump  -  -    -    X  X    X
> +pending-common-aarch64         -  -    -    -  X    -
> +
> +The legend row, shows the subdirectory entries.  These can be mapped
> +back to the priority.rhel entries, for example, for x86_64
> +
> +# x86_64
> +x86_64=generic:generic-x86:generic-x86-x86_64
> +x86_64-debug=generic:generic-x86:generic-x86-x86_64:debug:debug-x86-x86_64
> +
> +are combined into one entry for x86_64 where
> +
> +g maps to "generic"
> +ga1 maps to "generic-x86"
> +ga2 maps to "generic-x86-x86-64"
> +d maps to "debug"
> +da1 maps to nothing (more on this below)
> +da2 maps to debug-x86-x86_64
> +
> +The left hand column indicates the directory and config-variant.  For
> +example, ark-s390x-zfcpdump is the s390x-zfcpdump variant and the
> +row beside it shows the config settings in the ark directory.
> +
> +The data contained in the output can have 5 values:
> +
> +     y = CONFIG is set to 'y'
> +     m = CONFIG is set to 'm'
> +     n = CONFIG is set to 'is not set'
> +     - = CONFIG file does not exist
> +     X = CONFIG file entry is not in priority file
> +
> +As can be seen above in the CONFIG_HEADER_TEST output, da1 is not present
> +in the priority.rhel file and is marked with an 'X'.
> +
> +Options
> +=======
> +
> +     -c CONFIG
> +             Evalulate these specific CONFIGs. This can be a file,
> +             or a comma-separated list.  If nothing is specified then
> +             all CONFIGs are examined by default.)
> +     -d
> +             Enable debug
> +     -p priority.file
> +             Specify a priority.file (no default)
> +     -j
> +             Evaluate common directory
> +     -f
> +             Evaluate and fix a priority's CONFIGs
> +
> +All commands except -j require a -p argument.
> +
> +Evaluate CONFIGs
> +================
> +
> +The -f option can be used to evaluate all the CONFIGs by executing, for
> +example
> +
> +# evaluate_configs -p priority.rhel -f
> +
> +or a single CONFIG
> +
> +# evaluate_configs -p priority.rhel -f -c CONFIG_HEADER_TEST
> +
> +The Evaluate Output will show a different view than the Basic Output above:
> +
> +ERROR: (hierarchy) ark/generic/CONFIG_HEADER_TEST : superseding value has y.
> +|CONFIG_HEADER_TEST (ark-aarch64)
> +|g  ga1  ga2  d  da1  da2  g  ga1  ga2  d  da1  da2  g  ga1  ga2  d  da1  da2
> +|y  -    -    -  X    -    y  -    -    -  X    -    -  -    -    -  X    -
> +| Deleting ark/generic/CONFIG_HEADER_TEST
> +
> +This view is the Basic Output's aarch64 data in a single line,  From the
> +above output,
> +
> +common-aarch64                 y  -    -    -  X    -
> +ark-aarch64                    y  -    -    -  X    -
> +pending-common-aarch64         -  -    -    -  X    -
> +
> +The Evaluate output makes it easier to visually see a conflict.   One
> +can read the line and if there are two y|m|n separated by one or more - or
> +X's in a line, then there is the possibility of a conflict.
> +
> +If the CONFIG setting is found to be incorrect it it automatically removed
> +and a message
> +
> +| Deleting ark/generic/CONFIG_HEADER_TEST
> +
> +will be output.
> +
> +Evaluate common Directory
> +=========================
> +
> +This function does a 1-to-1 comparison of CONFIG settings in the
> +ark and fedora directories, and checks to see if the CONFIG should be set
> +in the common directory.
> +
> +The output is the same as the Evaluate output.
> +
> +This functionality uses the priority.common file and can be executed via
> +
> +evaluate_configs -j
> +
> +for all CONFIGs, or
> +
> +evaluate_configs -j -c CONFIG_HEADER_TEST
> +
> +for a single CONFIG.
> diff --git a/redhat/configs/evaluate_configs b/redhat/configs/evaluate_configs
> index 5ed3e0407bca..613a9dbf8537 100755
> --- a/redhat/configs/evaluate_configs
> +++ b/redhat/configs/evaluate_configs
> @@ -1,528 +1,896 @@
> -#!/bin/bash
> -#
> -# The order of priority is
> -#
> -#    debug/arch highest (ie, this can override the remaining levels)
> -#    debug/
> -#    generic/arch
> -#    generic/   lowest (ie, this value can be overridden by anything above)
> -#
> -# however, inheritance is the opposite.  That is if a CONFIG is undefined
> -# the lower level's config is inherited at the higher level.
> -#
> -# ex) Consider CONFIG_MLX4_EN
> -# which is set as
> -#                                         s390x
> -#    arch    aarch64 ppc64le s390x x86_64 zfcpd
> -#
> -#    d_a       x       x       x      x     x   <<< generic/s390x/zfcpdump
> -#    debug     x       x       x      x     |   <<< noop for s390/zfcpdump
> -#    gen_a     m       m       m      m     m   <<< same as s390x
> -#    gen       n       n       n      n     n
> -#
> -# where
> -#    x = no file/undefined
> -#    n = not set
> -#    m = module
> -#    y = built in
> -#    c = character/string setting
> -#
> -# The arch-debug configs would have m, as it is inherited from gen_a.
> -# All the arch configs would have m, because gen_a overrode gen.
> -#
> -# Obviously, the debug and gen rows will have the same setting as there
> -# is one setting for all arches.
> -#
> -# Rules:
> -# 1) If an entire arch row is majority m/y/n, then the generic/debug row 
> should
> -# be m/y/n.
> -# 2) A column should not have back-to-back identical settings, ex) m followed
> -# by an m.
> -# 3) debug can have the same setting as gen.  The config set is described
> -# in the priority file.
> -# 4) make as few as files as possible.  That might sound crazy but consider 
> the
> -# example above.  gen_a has separate files which are all =m.  It is more
> -# correct to have a single gen file =m.
> -#
> -# TODO: Inherit priority map from priority file?
> -# TODO: What to do with character & string configs?
> -# TODO: Can some of the syntax errors be cleaned up?  For example blank 
> lines,
> -# or comment on the same line as a config?
> -#
> -
> -DIR=./
> -
> -usage()
> -{
> -     echo "evaluate_configs [ -b | -c | -d | -s | -f ]"
> -     echo "  -b : balance level (generic, generic/arch, debug, debug/arch) 
> CONFIGs"
> -     echo "  -c : check arch CONFIGs"
> -     echo "  -d : enable debug"
> -     echo "  -s : check CONFIGs syntax"
> -     echo "  -f : find dead CONFIGs"
> +#!/usr/bin/bash
> +trap '[ -d "$tempdir" ] && rm -rf "$tempdir"' EXIT INT
> +
> +# TODO: -c takes a comma separated list or file?
> +# TODO: allow for user to specify CONFIGS ^^^ ?
> +# TODO: move the undo the p setting to map_configs_to_array
> +# TODO: Fix ERROR: message so it only shows when the file is being deleted
> +
> +DEBUG=false
> +
> +# global definitions
> +CONFIG=
> +priority_file=
> +ORDER=
> +cfgvariants=
> +toplevels=
> +subdirs=
> +rows=
> +columns=
> +configmap=
> +cfgs=
> +cfgs_base=
> +weightorig=
> +numorder=
> +longheader=
> +weightorig=
> +weight=
> +
> +tempdir=$(mktemp -d)
> +
> +whatcouldgowrong() {
> +     echo ""
> +     echo "usage: evaluate_configs [-c CONFIG] [-d] [-j] [ -p priority_file]"
                                                  ^--- add [-f] above

And sorry Prarit, still some -x references remains, like in help output below:

> +     echo ""
> +     echo "      -c CONFIG          Evalulate specific CONFIGs (file or csl)"
> +     echo "      -d                 Enable debug"
> +     echo "      -p priority.file   Specify a priority.file (no default)"
> +     echo "      -j                 Evaluate common directory"
> +     echo "      -f                 Evaluate CONFIGs"
> +     echo ""
> +     echo "examples)"
> +     echo ""
> +     echo "To show the status of CONFIG_HEADER_TEST in ARK,"
> +     echo "  ./evaluate_configs -p priority.rhel -c CONFIG_HEADER_TEST"
> +     echo ""
> +     echo "To fix all the CONFIGS in Fedora,"
> +     echo "  ./evaluate_configs -p priority.fedora -x"
> +     echo ""
> +     echo "To fix only CONFIG_HEADER_TEST in RHEL,"
> +     echo "  ./evaluate_configs -p priority.fedora -c CONFIG_HEADER_TEST -x"
> +     echo ""
> +     echo "To fix the common directory entries,"
> +     echo " ./evaluate_configs -j"
>       echo ""
> -     echo "See redhat/docs/editing_CONFIGS.txt for more information"
>       exit 1
>  }
>  
> -#
> -# read_file: Read a config file and return n (is not set), y (=y), m (=m),
> -# c (for a character setting or a file that contains only comments), and
> -# x if the file does not exist.
> -#
> -read_file() # $1 is the full file path
> -{
> -     filepath=$1
> -     if test -e $filepath; then
> -             egrep "# CONFIG.*is not set" $filepath >& /dev/null && echo "n" 
> && return
> -             egrep "CONFIG.*=" $filepath >& /dev/null
> -             if [ $? -eq 0 ]; then
> -                     egrep "=y" $filepath >& /dev/null && echo "y" && return
> -                     egrep "=m" $filepath >& /dev/null && echo "m" && return
> -                     # some files may equal a number or a string
> -                     egrep "=*" $filepath >& /dev/null && echo "c" && echo 
> $filepath >> $DIR/.strlist && return
> +# Get a list of the config-variants
> +get_cfgvariants() { # uses priority_file
> +     local configvariant
> +     local cfgvariant
> +
> +     # The priority files have a config-variant, followed by a hierarchy of
> +     # directories to examine for that config level.  The directories have
> +     # '-' instead of '/'.
> +     #
> +     # For example,
> +     #
> +     # ppc64le-debug=generic:generic-powerpc:debug:debug-powerpc
> +     #
> +
> +     while read -r configvariant
> +     do
> +             # ignore any line with whitespace
> +             test -z "$configvariant" && continue
> +             # ignore any line beginning with a #
> +             [[ "$configvariant" == \#* ]] && continue
> +             # ignore any line beginning with ORDER
> +             [[ "$configvariant" == ORDER* ]] && continue
> +             # ignore any line beginning with EMPTY
> +             [[ "$configvariant" == EMPTY* ]] && continue
> +
> +             # -debug variants must include the base variant
> +             # does the priority file contain a debug variant?
> +             cfgvariant=$(echo "$configvariant" | cut -d "=" -f 1)
> +             if grep -q "$cfgvariant-debug" "$priority_file"; then
> +                     # if it does, skip this variant and only use -debug
> +                     continue
>               fi
> -     else
> -             echo "x" # file does not exist
> -             return
> -     fi
> -     # some files may contain only comments
> -     echo "c"
> +
> +             # if this variant has a -debug, remove the -debug
> +             cfgvariant=$(echo "$cfgvariant" | awk -F "-debug" ' { print $1 
> } ')
> +
> +             # output "cfgvariant | configorder"
> +             echo "$cfgvariant | $(echo "$configvariant" | cut -d "=" -f 2 | 
> tr : " " )"
> +     done < $priority_file
>  }
>  
> -#
> -# get_arch_files: Read the value of a config for all arches.
> -#
> -# For example, 'get_arch_files generic CONFIG_FOO' would read
> -# the generic/aarch64/CONFIG_FOO, generic/powerpc64le/CONFIG_FOO, etc.
> -# and return a string like 'xynnn'.  Note that the last character
> -# is the s390x/zfcpdump entry.
> -#
> -get_arch_files() # $1 is directory, $2 is CONFIG
> -{
> -     # The second s390x entry is really s390x/zfcpdump
> -     for arch in "aarch64" "powerpc64le" "s390x" "x86_64" "s390x"
> +# Find top level dirs for each ORDER. These are normally just debug and 
> config.
> +get_toplevel_dirs() { # uses cfgvariants
> +     local cfg
> +     local cfgvariant
> +
> +     # anything with a dash(-) in it is a subdir
> +     echo "$cfgvariants" | while read -r cfgvariant
>       do
> -             # Need to special case generic powerpc64 & powerpc64le
> -             # because they have an extra "hop" between them at
> -             # the arch level
> -             [ "$arch" == "powerpc64le" ] && [ -e $DIR/$1/powerpc64/$2 ] && 
> arch=powerpc64
> -             val=$(read_file $DIR/$1/$arch/$2)
> -             echo -n $val
> -     done
> -     echo ""
> +             cfg=$(echo "$cfgvariant" | cut -d "|" -f 2)
> +             for i in $cfg
> +             do
> +                     echo "$i" | grep -v "-"
> +             done
> +     done | sort -u | tr '\n' ' '
>  }
>  
> -#
> -# get_config_files: Read the config files and return the data
> -# in a matrix.
> -# ex) Consider CONFIG_MLX4_EN
> -# which is set as
> -#                                         s390x
> -#    arch    aarch64 ppc64le s390x x86_64 zfcpd
> -#
> -#    d_a       x       x       x      x     x   <<< generic/s390x/zfcpdump
> -#    debug     x       x       x      x     |   <<< noop for s390/zfcpdump
> -#    gen_a     m       m       m      m     m   <<< same as s390x
> -#    gen       n       n       n      n     n
> -#
> -# would be returned as
> -#
> -#    xxxxx
> -#    xxxxx
> -#    mmmmm
> -#    nnnnn
> -#
> -get_config_files() # $1 is CONFIG
> -{
> -     generic=$(read_file $DIR/generic/$1)
> -     generic_arch=$(get_arch_files generic $1)
> -     debug=$(read_file $DIR/debug/$1)
> -     debug_arch=$(get_arch_files debug $1)
> -     zfcpdump=$(read_file $DIR/generic/s390x/zfcpdump/$1)
> -
> -     # debug/arch
> -     echo "${debug_arch::-1}$zfcpdump"
> -     # debug, the 'x' at the end is for s390x/zfcpdump
> -     echo "${debug}${debug}${debug}${debug}x"
> -     # generic/arch
> -     echo $generic_arch
> -     # generic
> -     echo $generic$generic$generic$generic$generic
> +# For each top level count subdirs and find max subdirs for each top level
> +get_subdirs() { # uses $cfgvariants and $toplevels
> +     local max
> +     local LINE
> +     local count
> +     local toplevel
> +
> +     for toplevel in $toplevels
> +     do
> +             max=0
> +             count=0
> +             OLDIFS=$IFS; IFS=$'\n'; for LINE in "$cfgvariants"
> +             do
> +                     LINE=$(echo "$LINE" | cut -d "|" -f 2)
> +                     count=0
> +                     IFS=$' '; for i in $LINE
> +                     do
> +                             echo "$i" | grep -q -v $toplevel && continue
> +                             count=$(echo "$i" | awk -F "-" '{print NF-1}')
> +                             [ "$max" -lt "$count" ] && max="$count"
> +                     done
> +             done
> +             IFS=$OLDIFS
> +             echo "$toplevel subdirs $((max + 1))"
> +     done
>  }
>  
> -#
> -# reconstruct_file: return the CONFIG file at a specific location in
> -# the matrix.  For example, (1,3) would be generic/powerpc64le.
> -#
> -reconstruct_file() # $1 is CONFIG, $2 a x-coordinate  $3 is the y-coordinate
> -{
> -     _dir=$3
> -     # X-axis: "aarch64" "powerpc64le" "s390x" "x86_64" "s390x zfcpdump"
> -     case $2 in
> -     0)      arch="aarch64";;
> -     1)      arch="powerpc64le";;
> -     2)      arch="s390x";;
> -     3)      arch="x86_64";;
> -     4)
> -             arch="s390x/zfcpdump"
> -             #(4,0) is interpreted as generic/s390x/zfcpdump (4,2)
> -             [ $_dir -eq 0 ] && _dir=2
> -             ;;
> -     esac
> +# For each config-variant, find missing sub-directories and mark them as 
> "EMPTY"
> +# This is very helpful for stage 3.
> +fix_config_variants() { # uses $toplevels, $subdirs, $cfgvariants
>  
> -     # Y-axis: debug-arch,debug,generic-arch,generic
> -     case $_dir in
> -     0)
> -             # Need to special case generic powerpc64 & powerpc64le
> -             # because they have an extra "hop" between them at
> -             # the arch level
> -             [ "$arch" == "powerpc64le" ] && [ -e $DIR/debug/powerpc64/$1 ] 
> && arch="powerpc64"
> -             dir="debug/$arch";;
> -     1)      dir="debug";;
> -     2)
> -             # Need to special case generic powerpc64 & powerpc64le
> -             # because they have an extra "hop" between them at
> -             # the arch level
> -             [ "$arch" == "powerpc64le" ] && [ -e $DIR/generic/powerpc64/$1 
> ] && arch="powerpc64"
> -             dir="generic/$arch";;
> -     3)      dir="generic";;
> -     esac
> +for toplevel in $toplevels
> +do
> +     local subdircnt
> +     local linenum
> +     local cfgvariant
> +     local LINE
> +     local count
> +     local oldentry
> +     local newentry
> +     local found
> +     local dashcount
> +     local new
> +
> +     subdircnt=$(echo "$subdirs" | grep "$toplevel" | awk -F "subdirs" ' { 
> print $2 } ')
> +     linenum=0
> +     echo "$cfgvariants" | while read -r cfgvariant
> +     do
> +             linenum=$((linenum + 1))
> +             # this seems strange to immediately reset cfgvariant but we
> +             # want the value from the file, not the one in memory.  The
> +             # value in the file may have been modified by a previous
> +             # toplevel.
> +             cfgvariant=$(sed "${linenum}q;d" "$tempdir"/cfgvariants)
> +
> +             LINE=$(echo "$cfgvariant" | cut -d "|" -f 2)
> +
> +             $DEBUG && echo "LINE=$LINE"
> +             # get the actual number of subdirs
> +             count=$(for i in $LINE
> +             do
> +                     echo "$i" | grep -q -v "$toplevel" && continue
> +                     echo "$i" | awk -F "-" '{print NF-1}'
> +             done | wc -l)
>  
> -     echo "$DIR/$dir/$1"
> -}
> +             [ -z "$count" ] && continue
> +             $DEBUG && echo "count=$count"
>  
> -#
> -# create_file: Create a config file
> -#
> -create_file() # $1 is the CONFIG, $2 is the filename, $3 is the value 
> (m/n/x/y)
> -{
> -     case $3 in
> -     x) rm -f $2;;
> -     n) echo "# $1 is not set" > $2 ;;
> -     m) echo "$1=m" > $2 ;;
> -     y) echo "$1=y" > $2 ;;
> -     esac
> -}
> +             # if the number of subdirs is the same, then bail
> +             [ "$count" -eq "$subdircnt" ] && continue
>  
> -#
> -# syntax_check: Check the syntax of a config file.  Files cannot be
> -# empty, and must be one of "is not set", "=y", "=m".
> -#
> -syntax_check() # $1 is the config filename
> -{
> -     num=$(cat $1 | wc -l)
> -     # 0 length is always bad (empty)
> -     [ $num -eq 0 ] && echo "$1 has zero length" && return 0
> -     # most files are length one, so special case it
> -     if [ $num -eq 1 ]; then
> -             egrep -E "^#.*is not set" $1 >& /dev/null && return 0
> -             egrep -E "^CONFIG.*=" $1 >& /dev/null && return 0
> -     fi
> +             $DEBUG && echo "missing entries LINE=$LINE"
> +             oldentry=$(for i in $LINE
> +             do
> +                     echo "$i" | grep -q "$toplevel" && echo "$i" | tr "\n" 
> " "
> +             done| xargs)
> +             $DEBUG && echo "oldentry=|$oldentry|"
>  
> -     # all comments are okay.
> -     numcomments=$(egrep "^#" $1 | wc -l)
> -     [ $numcomments -eq $num ] && return 0
> +             # Find the missing entry
> +             found=$(for i in $oldentry
> +             do
> +                     dashcount=$(echo "$i" | awk -F "-" '{print NF-1}')
> +                     dashcount=$((dashcount + 1))
> +                     echo $dashcount
> +             done | tr "\n" " ")
> +             $DEBUG && echo "found=$found"
> +
> +             # build the missing entry
> +             count=1
> +             newentry=$(for i in $(seq 1 "$subdircnt")
> +             do
> +                     if echo "$found" | grep -q "$i"; then
> +                             echo "$oldentry" | cut -d " " -f "$count"
> +                             count=$((count + 1))
> +                     else
> +                             echo "${toplevel}-EMPTY$((i - 1))"
> +                     fi
> +             done | tr "\n" " " | xargs)
> +             $DEBUG && echo "newentry=|$newentry|"
>  
> -     numcomments=$((numcomments + 1))
> -     if [ $numcomments -eq $num ]; then
> -             option=$(egrep -v "^#" $1)
> -             egrep -v "^#" $1 | egrep -E "^CONFIG.*=" >& /dev/null && return > 0
> -     fi
> -     echo "$1 is not correct"
> -     cat $1
> -     return 1
> +             # insert the missing entry
> +             if echo "$LINE" | grep -q "$toplevel"; then
> +                     new=${cfgvariant//$oldentry/$newentry}
> +             else
> +                     # Assuming that there is always a generic entry
> +                     # followed by a debug entry.  If a debug only config
> +                     # variant exists, there is a possibility that this
> +                     # screws up badly because the EMPTY tags are always
> +                     # added the end of the string. #FIXME
> +                     new="$cfgvariant $newentry"
> +             fi
> +
> +             $DEBUG && echo "REPLACED:"
> +             $DEBUG && echo "orig=$cfgvariant"
> +             $DEBUG && echo " new=$new"
> +
> +             sed -i "${linenum}s/${cfgvariant}/${new}/" 
> "$tempdir"/cfgvariants
> +
> +             $DEBUG && echo "----------------------------"
> +     done
> +done
>  }
>  
> -#
> -# check_overrides: Do the requested arch overrides need to be set?
> -#
> -# On any column, if a higher level has the same option as a lower level, and 
> is
> -# separated from the lower level by 0 or more unset configs, then the higher
> -# level option is not necessary.
> -#
> -check_overrides()
> -{
> -     local CONFIG=$1
> -     config_data=$(get_config_files $CONFIG)
> -
> -     # some examples of rules
> -     # - arch/generic can be a mix of y/m/n/c and generic can be xxxx
> -     # - arch/generic can be all y/m/n/c and generic cannot be xxxx
> -     # - arch/generic cannot be the same as generic
> -     # - debug cannot be the same as arch/generic
> -     # - debug cannot be the same as generic if arch/generic is the same
> -     #   as generic or if arch/generic is xxxx
> -     # - arch/debug cannot be the same as debug
> -     # - arch/debug can be a mix of y/m/n/c and debug can be xxxx
> -     # - arch/debug can be all y/m/n/c and debug cannot be xxxx
> -
> -     # x/y/m/n/c are valid values
> -     # find the errors
> -     # look at each entry in debug_arch and work "down" to generic.
> -
> -     echo "$config_data" | grep "c" >& /dev/null
> -     [ $? -eq 0 ] && return 0
> -
> -     x=0
> -     # All four arches must vote to remove a debug or generic entry
> -     configvote=( 1 4 1 5 )
> -     while [ $x -le 4 ]
> +# create a configmap
> +get_configmap() { # uses $ORDER and $cfgvariants
> +     local configvariant
> +     local arch
> +     local _configorder
> +     local configorder
> +     local order
> +
> +     for order in $ORDER
>       do
> -             y=0
> -             old="x"
> -             while [ $y -le 3 ]
> -             do
> -                     str=$(echo "$config_data" | sed -n "$((y + 1)){p;q}")
> -                     new=${str:$x:1}
> -
> -                     if [ "$old" == "x" ]; then
> -                             old=$new
> -                             oldx=$x
> -                             oldy=$y
> -                     elif [ "$old" == "$new" ]; then
> -                             configvote[$oldy]=$((configvote[$oldy] - 1))
> -                             [ "$DEBUG" ] && echo "$CONFIG: warning $old 
> ($oldx, $oldy) and $new ($x,$y) is invalid!"
> -                             [ "$DEBUG" ] && echo 
> "configvote[$oldy]=${configvote[$oldy]}"
> -                             [ "$DEBUG" ] && echo "$config_data"
> -                             if [ ${configvote[$oldy]} -eq 0 ]; then
> -                                     # the old coordinates point to the error
> -                                     filename=$(reconstruct_file $CONFIG 
> $oldx $oldy)
> -                                     [ "$DEBUG" ] && echo "file $filename 
> deleted!"
> -                                     rm -f $(reconstruct_file $CONFIG $oldx 
> $oldy)
> -                                     return 1
> -                             fi
> +             # jforbes: pending-fedora can be dropped.  It should be empty
> +             # most of the time.
> +             [ "$order" == "pending-fedora" ] && continue
>  
> -                     elif [ "$new" != "x" ]; then
> -                             old=$new
> -                             oldx=$x
> -                             oldy=$y
> -                     fi
> -                     y=$((y + 1))
> +             echo "$cfgvariants" | while read -r configvariant
> +             do
> +                     arch=$(echo "$configvariant" | cut -d "|" -f 1)
> +                     _configorder=$(echo "$configvariant" | cut -d "|" -f 2 
> | tr : " " )
> +                     configorder=$(for c in $_configorder
> +                     do
> +                             echo -n "${order}-${c} "
> +                     done; echo "")
> +
> +                     echo "${order}-$arch | $configorder"
>               done
> -             x=$((x + 1))
>       done
> -
> -     return 0
>  }
>  
> -#
> -# balance_check: Are the requested config files optimally set?
> -#
> -# On any row, if a higher level has a majority of set options that are the
> -# opposite (for example, y vs n, or m vs n) of a lower level, and is only
> -# separated by 0 or more rows of unset configs, then the lower level's value
> -# should be set to the majority value of the higher level. (balance)
> -#
> -balance_check() # $1 is CONFIG, $2 is generic or debug arch string,
> -             # $3 is the y-axis (ie, generic arch(2) or debug arch(0))
> -{
> -     local CONFIG=$1
> -     local _arch=$2
> -     local _yaxis=$3
> +# pretty output
> +output_pretty_cfgs() { # uses cfgs and configmap, rows, and columns
> +     local x
> +     local index
> +     local _configmap
>  
> -     # if this is a character setting then return
> -     echo $_arch | grep c >& /dev/null
> -     [ $? -eq 0 ] && return
> +     index=0
> +     for x in $(seq 1 $rows)
> +     do
> +             [ "$x" == 1 ] && echo "legend" "$1"
> +             _configmap=$(echo "$configmap" | sed "${x}q;d" | cut -d "|" -f 
> 1)
> +                     echo "$_configmap ${cfgs[@]:$index:$columns}"
> +             index=$((index + columns))
> +     done | column -t
> +}
>  
> -     [ $_yaxis -eq 0 ] && _path="debug" || _path="generic"
> +# helper function to remove a CONFIG file
> +delete_file() {
> +     local position
> +     local configentry
> +
> +     position=$1
> +     configentry=$2
> +     # if the entry doesn't exist, decrease weight by 1
> +     weight[$position]=$((weight[$position] - 1))
> +     if [ "${weight[$position]}" -le 0 ]; then
> +             if [ -e "$configentry" ]; then
> +                     $DEBUG && echo "| Deleting $configentry 
> ${weight[$position]})" || echo "| Deleting $configentry"
> +                     rm -f "$configentry"
> +             fi
> +     else
> +             $DEBUG && echo "| Not deleted.  Required by other config 
> variants (${weight[$position]})"
> +     fi
> +}
>  
> -     # are there 3 of the same character in the string?
> -     for mnxy in 'm' 'n' 'y' 'x'
> +# find duplicate entries
> +fix_broken_arches() { # uses ORDER, crows, columns, and configmap
> +     local row
> +     local x
> +     local y
> +     local value
> +     local _value
> +     local char
> +     local position
> +     local curr
> +
> +     # See comment about weight in create_output_header()
> +     weight=("${weightorig[@]}")
> +
> +     # This search is handled differently than
> +     # output_pretty_cfgs().  A string is created that
> +     # is only for the specific cfg-variant (row * numorder
> +     # long).  This string is easier to evaluate.
> +     for row in $(seq 0 $((crows - 1)))
>       do
> -             res="${_arch//[^${mnxy}]}"
> -             [ ${#res} -ge 3 ] && break
> -     done
> -     [ "$mnxy" == 'x' ] && return
> -
> -     # in theory the CHECKOVERRIDES case has taken care of the
> -     # possiblity of $mnxy being the same $level.  Better to
> -     # be safe than sorry.
> -     level=$(read_file $DIR/$_path/$CONFIG)
> -     if [ "$mnxy" != "$level" ]; then
> -             [ "$DEBUG" ] && echo "balancing $CONFIG"
> -             [ "$DEBUG" ] && echo "$CONFIG (mnxy=$mnxy)"
> -             [ "$DEBUG" ] && echo "OLD:"
> -             [ "$DEBUG" ] && get_config_files $CONFIG
> -             # demote level to x-arch
> -             if [ $_yaxis -eq 2 ] && [ "$level" != "x" ]; then
> -                     level_cap=$(echo $level | tr '[:lower:]' '[:upper:]')
> +             # construct the string of values to view
> +             value=$(for order in $(seq 0 $((numorder - 1)))
> +             do
> +                     index=$(((order * (crows * columns)) + (row * columns)))
> +                     echo -n "${cfgs[@]:$index:$columns} "
> +             done
> +             echo "")
> +             $DEBUG && echo "row=$row $value"
> +
> +             # check to see if there is a config setting conflict
> +             _value=$(echo "$value" | tr -d " X-")
> +             if echo "$_value" | grep -q "yy\|mm\|nn"; then
> +                     # go through the value string, ex) y-y-Xm-,
> +                     # and find the characters that match the
> +                     # previous character.
> +                     curr="p"
> +                     position=0
> +                     # use value here as each character is
> +                     # separated by a space
> +                     for char in $value
> +                     do
> +                             index=$(( ((crows * columns) * (position / 
> columns)) + (row * columns) + (position % columns) ))
> +                             # sed is 1-based so add 1 to x and y
> +                             y=$(((index / columns) + 1))
> +                             # configmap contains the cfgvariant and a
> +                             # pipe (+3), and needs to be 1-based
> +                             x=$(((index % columns) + 4))
> +                             $DEBUG && echo "($x,$y) $index"
> +
> +                             configentry="$(echo "$configmap" | sed 
> "${y}q;d" | cut -d " " -f "$x" | tr "-" "/")/$CONFIG"
> +                             cfgvariant=$(echo "$configmap" | sed "${y}q;d" 
> | cut -d " " -f 1)
> +
> +                             # if this, char, is the same as curr then
> +                             # there is a conflict and char needs to
> +                             # be changed.
> +                             if [ "$char" == "$curr" ]; then
> +                                     echo ""
> +                                     echo "ERROR: (hierarchy) $configentry : 
> superseding value has $curr."
> +                                     echo "|$CONFIG ($cfgvariant)"
> +                                     printf "|$longheader\n|$value" | column 
> -t
> +                                     $DEBUG && echo "position=$position | 
> $(echo "$value" | cut -d " " -f $((position + 1)) ) | 
> weight=${weight[$position]}"
> +
> +                                     # See comment about weight in
> +                                     # create_output_header()
> +                                     delete_file "$position" "$configentry"
> +                                     break
> +                             fi
> +                             case "$char" in
> +                             '-')
> +                                     ;;
> +                             'X')
> +                                     # See comment about weight in
> +                                     # create_output_header()
> +                                     delete_file "$position" "$configentry"
> +                                     ;;
> +                             * )
> +                                     curr=$char
> +                                     ;;
> +                             esac
> +                             position=$((position + 1))
> +                     done
>               else
> -                     level_cap="N"
> +                     # still have to examine this string because it may
> +                     # contain "X", which has to be accounted for in
> +                     # the weights.
> +                     echo "$value" | grep -q "X" || continue
> +                     position=0
> +                     for char in $value
> +                     do
> +                             if [ "$char" == 'X' ]; then
> +                                     index=$(( ((crows * columns) * 
> (position / columns)) + (row * columns) + (position % columns) ))
> +                                     # sed is 1-based so add 1 to x and y
> +                                     y=$(((index / columns) + 1))
> +                                     # configmap contains the cfgvariant and
> +                                     # a pipe (+3), and needs to be 1-based
> +                                     x=$(((index % columns) + 4))
> +                                     $DEBUG && echo "($x,$y) $index"
> +
> +                                     configentry="$(echo "$configmap" | sed 
> "${y}q;d" | cut -d " " -f "$x" | tr "-" "/")/$CONFIG"
> +                                     cfgvariant=$(echo "$configmap" | sed 
> "${y}q;d" | cut -d " " -f 1)
> +                                     # See comment about weight in
> +                                     # create_output_header()
> +                                     delete_file "$position" "$configentry"
> +                             fi
> +                             position=$((position + 1))
> +                     done
>               fi
> -             _arch=$(echo $_arch | sed "s/x/$level_cap/g")
>  
> -             # promote and replace
> +     done
> +}
>  
> -             # set new level
> -             level=$mnxy
> -             _arch=$(echo $_arch | tr "$level" 'x' | tr  '[:upper:]' 
> '[:lower:]')
> -             for x in 0 1 2 3
> +# compare the common, fedora, and ark configs.
> +# By default this function uses the priority.common file
> +fix_common() { # uses cfgs, CONFIG, and ORDER
> +     local index
> +     local value
> +     local _value
> +     local x
> +     local y
> +     local configentry
> +     local _configentry
> +     local order
> +
> +     # the priority.common array is
> +     #       common configs
> +     #       ark configs
> +     #       fedora configs
> +     for index in $(seq 0 $(((crows * columns) - 1)))
> +     do
> +             # this string is the concatenation of the
> +             # common, ark, and fedora config values
> +             value=$(for order in $(seq 0 $((numorder -1)))
>               do
> -                     filename=$(reconstruct_file $CONFIG $x $_yaxis)
> -                     _arch_val="${_arch:$x:1}"
> -                     create_file $CONFIG $filename $_arch_val
> +                     echo -n "${cfgs[$(( (order * crows * columns) + 
> index))]}"
>               done
> -             filename=$(reconstruct_file $CONFIG $x $((_yaxis + 1)))
> -             create_file $CONFIG $filename $level
> -             # run CHECKOVERRIDES
> -             check_overrides $CONFIG
> -             [ "$DEBUG" ] && echo "NEW:"
> -             [ "$DEBUG" ] && get_config_files $CONFIG
> -     else
> -             echo "$CONFIG needs to run CHECKOVERRIDES"
> -             echo "  ./evaluate_configs -c $CONFIG"
> +             echo "")
> +
> +             # It doesn't matter what common is set to so
> +             # trim it off.
> +             _value="${value:1}"
> +             if echo "$_value" | grep -q "yy\|mm\|nn"; then
> +
> +                     # set _value to just y|m|n
> +                     _value="${_value:1}"
> +
> +                     # create a long array to see if the change is valid
> +                     checkvalue=$(for order in $(seq 0 $((numorder -1)))
> +                     do
> +                             step=$(( order * crows * columns))
> +                             # this seems weird but it rounds off to columns
> +                             row=$(( (step + index) / columns * columns))
> +                             echo -n "${cfgs[@]:$row:$columns} "
> +                     done; echo "")
> +
> +                     $DEBUG && echo "checkvalue=$checkvalue"
> +
> +                     IFS=', ' read -r -a checkvalue <<< "$checkvalue"
> +                     _index=$((index % columns))
> +
> +                     for order in $(seq 1 $((numorder -1)))
> +                     do
> +                             checkvalue[$((( order * columns ) + 
> _index))]='-'
> +                     done
> +                     $DEBUG && echo "updated checkvalue=${checkvalue[@]}"
> +
> +                     # set the common entry to _value, so that an analysis
> +                     # can be run on the other entries
> +                     checkvalue[$_index]="$_value"
> +
> +                     count=0
> +                     cfgvalue=${checkvalue[0]}
> +                     warning=false
> +                     for i in ${checkvalue[@]}
> +                     do
> +                             echo "$i" | grep -q 'm\|n\|y' && cfgvalue=$i
> +                             if [ $count == $_index ]; then
> +                                     if [ "$cfgvalue" != "$_value" ]; then
> +                                             $DEBUG && echo "$CONFIG 
> override will not work."
> +                                             warning=true
> +                                             break;
> +                                     fi
> +                                     _index=$((_index + columns))
> +                             fi
> +                             count=$((count + 1))
> +                     done
> +
> +                     $warning && break
> +
> +                     echo "$CONFIG found a match where common should be set."
> +
> +                     # sed is 1-based so add 1 to x and y
> +                     y=$(((index / columns) + 1))
> +                     # configmap contains the cfgvariant and a
> +                     # pipe (+3), and needs to be 1-based
> +                     x=$(((index % columns) + 4))
> +                     $DEBUG && echo "($x,$y) $index"
> +
> +                     # remove the existing ark and fedora configs
> +                     configentry="$(echo "$configmap" | sed "${y}q;d" | cut 
> -d " " -f "$x" | tr "-" "/")/$CONFIG"
> +                     for order in $ORDER
> +                     do
> +                             [ "$order" == "common" ] && continue
> +                             _configentry=${configentry//common/$order}
> +                             [ -e "$_configentry" ] && rm -f "$_configentry"
> +                     done
> +
> +                     # create a new common config
> +                     echo "$_value" in "$configentry"
> +                     case "$_value" in
> +                     m)
> +                             echo "${CONFIG}=m" > "$configentry"
> +                             ;;
> +                     y)
> +                             echo "${CONFIG}=y" > "$configentry"
> +                             ;;
> +                     n)
> +                             echo "# $CONFIG is not set" > "$configentry"
> +                             ;;
> +                     esac
> +             fi
> +     done
> +}
> +
> +# Check that ccolumns is consistent
> +debug_cfgvariants() { # uses $cfgvariants and sets crows and ccolumns
> +     local LINE
> +
> +     crows=$(echo "$cfgvariants" | wc -l)
> +
> +     ccolumns=$(echo "$cfgvariants" | while read -r LINE
> +     do
> +             LINE=$(echo "$LINE" | cut -d "|" -f 2)
> +             echo "$LINE" | wc -w
> +     done | sort -u)
> +
> +     # Error check columns
> +     if [ "$(echo "$ccolumns" | wc -l)" != "1" ]; then
> +             echo "ERROR in parser.  There were multiple length columns 
> found."
> +             echo "$ccolumns"
>               exit 1
>       fi
>  }
>  
> -# where am i?
> -if [ ! -d "generic" ] || [ ! -d "debug" ]; then
> -     echo "This script must be run in the redhat/configs directory."
> -     exit 1
> -fi
> +# Create an output header, a fancy long header for fix_broken_arches, and the
> +# weights
> +create_output_header() { # uses $ORDER, $configmap, and sets output_header
> +                      # and weightorig
> +
> +     local order
> +     local dir
> +     local convert
> +     local f
> +     local configline
> +
> +     # We know that the configmap now contains correct sized entries for
> +     # each arch.  The arch doesn't really matter and we just need the
> +     # information to make a header.
> +     order=$(echo "$ORDER" | cut -d " " -f 1)
> +     configline=$(echo "$configmap" | head -1 | cut -d "|" -f 2 | sed 
> "s/${order}-//g")
> +     for dir in $configline
> +     do
> +             convert=false
> +             if echo "$dir" | grep -q "-"; then
> +                     if echo "$dir" | grep -q "EMPTY0"; then
> +                             dir=$(echo "$dir" | awk -F "-EMPTY0" ' { print 
> $1 } ')
> +                             convert=true
> +                     fi
> +             else
> +                     convert=true
> +             fi
>  
> -CHECKOVERRIDES=""
> -SYNTAXCHECK=""
> -DEBUG=""
> -BALANCECHECK=""
> -FINDDEAD=""
> +             ! $convert && continue
>  
> -while [[ $# -gt 0 ]]
> -do
> -     key="$1"
> -     case $key in
> -     -b) BALANCECHECK="x";;
> -     -c) CHECKOVERRIDES="x";;
> -     -d) DEBUG="x";;
> -     -s) SYNTAXCHECK="x";;
> -     -f) FINDDEAD="x";;
> -     -h) usage;;
> -     *) break;;
> -     esac
> -     shift
> -done
> +             # get the first letter of each word
> +             f=$(echo "$dir" | head -c 1)
> +             $DEBUG && echo "directory $dir entries will be converted to $f"
> +             configline=${configline//$dir/$f}
> +     done
>  
> -if [ "$CHECKOVERRIDES" ] && [ "$1" ]; then
> -     ret=1
> -     while [ $ret -eq 1 ]
> +     # Go through the configline and convert the directory names into header
> +     # names For example,
> +     #    generic generic-x86 generic-x86-x86_64 generic-EMPTY3 debug-EMPTY0 
> debug-EMPTY1 debug-EMPTY2
> +     # will be converted to
> +     #    g ga1 ga2 ga3 d da1 da2
> +     output_header=$(for dir in $configline
>       do
> -             check_overrides $1
> -             ret=$?
> +             # convert dirs with no dashes to the same thing
> +             if ! echo "$dir" | grep -q "-"; then
> +                     echo "$dir"
> +                     continue
> +             fi
> +             f=$(echo "$dir" | cut -d "-" -f 1)
> +             # convert g-x86 to ga, and g-x86-x86_64 to ga2, etc.
> +             if echo "$dir" | grep -q "EMPTY"; then
> +                     numempty=$(echo "$dir" | awk -F "EMPTY" ' { print $2 } 
> ')
> +                     if [ "$numempty" -eq 0 ]; then
> +                             echo "$f"
> +                     else
> +                             echo "${f}a${numempty}"
> +                     fi
> +             else
> +                     numdashes=$(echo "$dir"| grep -o "-" | wc -l)
> +                     echo "${f}a${numdashes}"
> +             fi
> +     done | tr "\n" " ")
> +
> +     # create a weightorig array that contains the weights of change for
> +     # each directory.  This is useful for the -x option display

-x on this comment

> +     for entry in $output_header
> +     do
> +             if echo "$entry" | grep -q 'a'; then
> +                     _weightorig+=(1)
> +             else
> +                     _weightorig+=("$crows")
> +             fi
>       done
> -     exit 1
> -fi
>  
> -if [ "$CHECKOVERRIDES" ]; then
> -     rm -f $DIR/.strlist
> -     # only look for CONFIGs that are defined in multiple locations
> -     find $DIR -name CONFIG* -exec basename {} \; | sort | uniq -c | grep -v 
> ' 1 '|sed 's/.*CONFIG/CONFIG/' > .configlist
> -     while [ $(cat .configlist | wc -l) -ne 0 ]
> +     # It is possible (and valid) to have an subdir arch followed by
> +     # a debug entry.  The -x checker would have flagged this and
> +     # removed the file.  As a solution there is a weight associated
> +     # with each entry's CONFIG file.  A debug or generic entry has
> +     # a weight equal the number of columns, and the arch entries all
> +     # have a weight of one.  The -x tracker subtracts one for each "hit"
> +     # and only removes the file if the weight is 1.

More references to old -x parameter

> +
> +     weightorig=""
> +     longheader=""
> +     for order in $(seq 1 $numorder)
> +     do
> +             weightorig="${weightorig[@]} ${_weightorig[@]}"
> +             longheader="${longheader}${output_header}"
> +     done
> +     IFS=', ' read -r -a weightorig <<< "$weightorig"
> +}
> +
> +# initialize the array to '-' (undefined) and 'X' (not present/EMPTY)
> +init_cfgs() { #uses cfgs, rows, and columns
> +     unset cfgs
> +     eval "$(eval echo "cfgs[{1..$((rows * columns))}]='-'\;")"
> +     # the -'s can be a problem when being parsed by other commands.  I
> +     # tried using +, o, ., X, etc. but none of the output was as clear as
> +     # a dash.  Initialize the 0th element to an unused letter.  If still
> +     # 'p' it can be changed back later on.
> +     cfgs[0]=p
> +
> +     # set EMPTY configs to X
> +     for row in $(seq 0 $((rows - 1)))
>       do
> -             [ "$DEBUG" ] && cat .configlist | wc -l
> -             CONFIG=$(head -1 .configlist)
> -             ret=1
> -             while [ $ret -eq 1 ]
> +             index=$((row * columns))
> +             num=0
> +             for entry in $(echo "$cfgvariants" | sed "$(((row % crows) + 
> 1))q;d" | cut -d "|" -f 2)
>               do
> -                     check_overrides $CONFIG
> -                     ret=$?
> +                     echo "$entry" | grep -q EMPTY && cfgs[$((index + 
> num))]='X'
> +                     num=$((num + 1))
>               done
> -             # this has to be "exact" pattern
> -             sed -i "/\<$CONFIG\>/d" .configlist
>       done
> -fi
> +     cfgs_base=("${cfgs[@]}")
> +}
>  
> -if [ "$SYNTAXCHECK" ] && [ "$1" ]; then
> +# reset the configs to default
> +reset_cfgs() {
> +     unset cfgs
> +     cfgs=("${cfgs_base[@]}")
> +}
>  
> -     CONFIG=$1
> +# map the CONFIG files to the array
> +map_configs_to_array() { #uses CONFIG, configmap, cfgs
>  
> -     echo "Issues found by the syntax check are not auto-corrected.  You 
> must make"
> -     echo "manual changes and execute the syntax check again."
> -     syntax_check $CONFIG
> -     exit $?
> -fi
> +     local LINE
> +     local contents
> +     local _LINE
> +     local row
> +     local cols
> +     local col
>  
> -if [ "$SYNTAXCHECK" ]; then
> -     echo "Issues found by the syntax check are not auto-corrected.  You 
> must make"
> -     echo "manual changes and execute the syntax check again."
> -     find $DIR -name CONFIG_* | while read CONFIG
> +     for LINE in $(find ./ -name $CONFIG -printf '%P\n' | awk -F "/$CONFIG" 
> ' { print $1 } ')
> +     # loop through the CONFIG files
>       do
> -             syntax_check $CONFIG
> +             $DEBUG && echo "+-------------------"
> +             $DEBUG && echo "found: $LINE"
> +
> +             contents=$(grep "^# $CONFIG is not set\|^$CONFIG=" 
> "$LINE"/"$CONFIG")
> +             case $contents in
> +             "# $CONFIG is not set")
> +                     contents=n
> +                     ;;
> +             "${CONFIG}=y")
> +                     contents=y
> +                     ;;
> +             "${CONFIG}=m")
> +                     contents=m
> +                     ;;
> +             *)
> +                     echo "$LINE/$CONFIG has a strange entry ... skipping"
> +                     return 1
> +                     break;;
> +             esac
> +
> +             $DEBUG && echo "contents=$contents"
> +
> +             _LINE=$(echo "$LINE" | tr "/" "-")
> +             $DEBUG && echo "_LINE=$_LINE"
> +             # set each cfg to $contents
> +             OLDIFS=$IFS; IFS=$'\n'; for rowandcol in $(echo "$configmap" | 
> grep -n " $_LINE ")
> +             do
> +                     row=$(echo "$rowandcol" | cut -d ":" -f 1)
> +                     # grep is 1 based and we need a 0 based number
> +                     row=$((row - 1))
> +                     cols=$(echo "$rowandcol" | cut -d "|" -f 2)
> +                     $DEBUG && echo "row=$row"
> +                     $DEBUG && echo "cols=$cols"
> +
> +                     col=$(echo "$cols" | awk -F "$_LINE" ' { print $1 }' | 
> wc -w)
> +                     $DEBUG && echo "($col, $row) = $contents"
> +                     # convert the (col,row) to an index in the array
> +                     $DEBUG && echo "setting element $(($((row * columns)) + 
> col)) = $contents"
> +                     # set the config
> +                     cfgs[$(($((row * columns)) + col))]=$contents
> +             done
> +             IFS=$OLDIFS
>       done
> -fi
>  
> -if [ "$BALANCECHECK" ] && [ "$1" ]; then
> +     # undo the 'p' setting of the initial element
> +     # (setting to 'p' done in init_cfgs)
> +     [ "${cfgs[0]}" == "p" ] && cfgs[0]="-"
>  
> -     CONFIG=$1
> +     return 0
> +}
>  
> -     debug_arch=$(get_arch_files debug $CONFIG)
> -     # trim off s390x: It is handled in CHECKOVERRIDES
> -     debug_arch=$(echo ${debug_arch::-1})
> +#
> +#
> +# MAIN
> +#
> +#
>  
> -     balance_check $CONFIG $debug_arch 0
> +# PROCESS ARGUMENTS
> +FINDFIXES=false
> +FIXCOMMON=false
> +configs=
> +while getopts "c:dfhjp:" opt; do
> +     case ${opt} in
> +     c )
> +             configs=$OPTARG
> +             ;;
> +     d )
> +             DEBUG=true
> +             ;;
> +     f )
> +             # Find fixes per config-variant
> +             FINDFIXES=true
> +             ;;
> +     h )
> +             whatcouldgowrong
> +             ;;
> +     j )
> +             # jforbes mode
> +             priority_file=priority.common
> +             FIXCOMMON=true
> +             ;;
> +     p )
> +             # Get the high level order from the priority file
> +             priority_file=$OPTARG
> +             ;;
> +     *)
> +             whatcouldgowrong
> +             ;;
> +     esac
> +done
>  
> -     generic_arch=$(get_arch_files generic $CONFIG)
> -     # trim off s390x: It is not needed at this level
> -     generic_arch=$(echo ${generic_arch::-1})
> +$DEBUG && echo "priority_file=$priority_file"
> +$DEBUG && echo "configs=$CONFIG"
> +$DEBUG && echo "FINDFIXES=$FINDFIXES"
> +$DEBUG && echo "FIXCOMMON=$FIXCOMMON"
>  
> -     balance_check $CONFIG $generic_arch 2
> -     exit
> +# Do some simple error checking
> +if [ -z "$priority_file" ]; then
> +     echo "Specify a priority.* file"
> +     whatcouldgowrong
>  fi
>  
> -if [ "$BALANCECHECK" ]; then
> -     # only look for CONFIGs that are defined in multiple locations
> -     find $DIR -name CONFIG* -exec basename {} \; | sort | uniq -c | grep -v 
> ' 1 '|sed 's/.*CONFIG/CONFIG/' > .configlist
> -     while [ $(cat .configlist | wc -l) -ne 0 ]
> -     do
> -             [ "$DEBUG" ] && cat .configlist | wc -l
> -             CONFIG=$(head -1 .configlist)
> -
> -             debug_arch=$(get_arch_files debug $CONFIG)
> -             # trim off s390x: It is handled in CHECKOVERRIDES
> -             debug_arch=$(echo ${debug_arch::-1})
> -
> -             balance_check $CONFIG $debug_arch 0
> -
> -             generic_arch=$(get_arch_files generic $CONFIG)
> -             # trim off s390x: It is not needed at this level
> -             generic_arch=$(echo ${generic_arch::-1})
> -
> -             balance_check $CONFIG $generic_arch 2
> +# if configs is not set then do all CONFIGS
> +if [ -z "$configs" ]; then
> +     find ./ -name "CONFIG*" -type f -printf "%f\n" | sort -u > 
> "$tempdir"/CONFIGS
> +     configs=$tempdir/CONFIGS
> +fi
>  
> -             # this has to be "exact" pattern
> -             sed -i "/\<$CONFIG\>/d" .configlist
> +# if configs is still not set, then parse the argument provided
> +if [ ! -e "$configs" ]; then
> +# assume the user is smart enough to specify CONFIGs
> +     for config in ${configs//,/ }
> +     do
> +             # Allow users to specify configs without CONFIG_
> +             if ! echo "$config" | grep -q CONFIG; then
> +                     config="CONFIG_${config}"
> +             fi
> +             echo "$config" >> "$tempdir"/CONFIGS
>       done
> -     rm -f .configlist
> +     configs=$tempdir/CONFIGS
> +else
> +     # if the file exists just copy it
> +     [ ! -e "$tempdir"/CONFIGS ] && cp "$configs" "$tempdir"/CONFIGS
>  fi
>  
> -#
> -# Find configs that are requested but do not exist in the final .configs
> -#
> -if [ "$FINDDEAD" ]; then
> -     (cd ..; make dist-configs)
> -
> -     awk '
> -             /is not set/ {
> -                     split ($0, a, "#");
> -                     split(a[2], b);
> -                     print b[1] ;
> -             }
> -             /=/ {
> -                     split ($0, a, "=");
> -                     print a[1];
> -             }
> -     ' *.config | sort -u > .finalconfiglist
> -
> -     find ./ -name CONFIG_* | sed 's!.*/!!' | sort -u > .configlist
> -
> -     echo "These CONFIGS defined in redhat/configs but not the final 
> .configs have been deleted:"
> -     diff -u .finalconfiglist .configlist | grep "^+CONFIG" | sed 's/^+//g' 
> | while read FILENAME
> +ORDER=$(grep "^ORDER" "$priority_file"| cut -d "=" -f 2)
> +
> +# STEP 1.  Parse the priority file
> +
> +cfgvariants=$(get_cfgvariants)
> +$DEBUG && echo "----------------------------------------"
> +$DEBUG && echo "cfgvariants:"
> +$DEBUG && echo "$cfgvariants"
> +$DEBUG && echo "----------------------------------------"
> +toplevels=$(get_toplevel_dirs "$cfgvariants")
> +$DEBUG && echo "Top level directories in priority file: $toplevels"
> +subdirs=$(get_subdirs)
> +$DEBUG && echo "Top-level sub-directories:"
> +$DEBUG && echo "$subdirs"
> +
> +# Add EMPTY entries for each missing subdirectory level in the config
> +# variants
> +echo "$cfgvariants" > "$tempdir"/cfgvariants
> +fix_config_variants
> +$DEBUG && echo ""
> +$DEBUG && echo ""
> +$DEBUG && echo "Fixed: cfgvariants"
> +$DEBUG && cat "$tempdir"/cfgvariants
> +
> +# Reset cfgvariants to new values with EMPTYs.
> +# cfgvariants now contains the config-variant data with EMPTY subdirs.
> +cfgvariants=$(cat "$tempdir"/cfgvariants)
> +crows=
> +ccolumns=
> +debug_cfgvariants
> +$DEBUG && echo "For the config-variants there are $crows rows and $ccolumns 
> columns."
> +
> +# STEP 2.  Now that we have fixed the list of config variants, create a 
> config
> +# map that contains all entries wrt the ORDER specified in the priority file.
> +
> +numorder=$(echo "$ORDER" | wc -w)
> +# jforbes: pending-fedora can be dropped.  It should be empty
> +# most of the time.
> +echo "$ORDER" | grep -q "pending-fedora" && numorder=$((numorder -1))
> +
> +# configmap is the list of config-variants used for displaying and analyzing
> +# the CONFIGs.
> +configmap=$(get_configmap)
> +$DEBUG && echo " "
> +$DEBUG && echo "The configmap is:"
> +$DEBUG && echo "$configmap"
> +$DEBUG && echo " "
> +
> +# STEP 3.  Create an array and header to hold the configmap data.
> +
> +rows=$(echo "$configmap" | wc -l)
> +columns=$(echo "$configmap" | head -1 | cut -d "|" -f 2 | wc -w)
> +$DEBUG && echo "There are $rows rows and $columns columns in the configmap."
> +
> +create_output_header # sets output_header
> +$DEBUG && echo "output_header=|$output_header|"
> +$DEBUG && echo "longheader=|$longheader|"
> +$DEBUG && echo "output_header has weights ${weightorig[@]}"
> +
> +# create the cfgs array and initialize it to '-' (not found)
> +init_cfgs
> +
> +if $FINDFIXES; then
> +     while read -r CONFIG
>       do
> -             echo $FILENAME
> -             find ./ -name $FILENAME | xargs rm -f
> -     done
> +             reset_cfgs
> +             map_configs_to_array || continue
> +
> +             fix_broken_arches "$output_header"
> +     done < "$tempdir"/CONFIGS
> +     exit
> +fi
>  
> -     rm -f .configlist .finalconfiglist
> +if $FIXCOMMON; then
> +     while read -r CONFIG
> +     do
> +             reset_cfgs
> +             map_configs_to_array || continue
> +             fix_common
> +     done < "$tempdir"/CONFIGS
> +     exit
>  fi
>  
> +# only display the configs
> +     while read -r CONFIG
> +     do
> +             reset_cfgs
> +             map_configs_to_array || continue
> +             echo ""
> +             echo "$CONFIG"
> +             output_pretty_cfgs "$output_header"
> +     done < "$tempdir"/CONFIGS
>  exit
> diff --git a/redhat/configs/priority.common b/redhat/configs/priority.common
> new file mode 100644
> index 000000000000..d4b907182446
> --- /dev/null
> +++ b/redhat/configs/priority.common
> @@ -0,0 +1,28 @@
> +ORDER=common ark fedora
> +
> +# x86_64
> +x86_64=generic:generic-x86:generic-x86-x86_64
> +x86_64-debug=generic:generic-x86:generic-x86-x86_64:debug:debug-x86-x86_64
> +
> +# i686
> +i686=generic:generic-x86:generic-x86-i686
> +i686-debug=generic:generic-x86:generic-x86-i686:debug:debug-x86
> +
> +# ppc64le
> +ppc64le=generic:generic-powerpc
> +ppc64le-debug=generic:generic-powerpc:debug:debug-powerpc
> +
> +# s390x
> +s390x=generic:generic-s390x
> +s390x-debug=generic:generic-s390x:debug:debug-s390x
> +s390x-zfcpdump=generic:generic-s390x:generic-s390x-zfcpdump
> +
> +# aarch64
> +aarch64=generic:generic-arm:generic-arm-aarch64
> +aarch64-debug=generic:generic-arm:generic-arm-aarch64:debug:debug-arm-aarch64
> +
> +# arm
> +armv7hl=generic:generic-arm:generic-arm-armv7:generic-arm-armv7-armv7
> +armv7hl-debug=generic:generic-arm:generic-arm-armv7:generic-arm-armv7-armv7:debug:debug-arm
> +armv7hl-lpae=generic:generic-arm:generic-arm-armv7:generic-arm-armv7-lpae
> +armv7hl-lpae-debug=generic:generic-arm:generic-arm-armv7:generic-arm-armv7-lpae:debug:debug-arm
> diff --git a/redhat/configs/priority.fedora b/redhat/configs/priority.fedora
> index 362d7ff6c332..73fa2bad2d1f 100644
> --- a/redhat/configs/priority.fedora
> +++ b/redhat/configs/priority.fedora
> @@ -1,4 +1,18 @@
> -# config-variant=config:config:config
> +# Entries must be ordered as base and debug (if the debug variant exists)
> +# ie) config-variant-arch
> +#     config-variant-arch-debug (if the -debug variant exists)
> +
> +# Individual entries must be ordered as
> +# config-variant=config-1:config-2:config-3 in a descending order through
> +# the hierarchy
> +
> +# -debug variants must include the entirety of the base variant
> +# For example,
> +#
> +# config-foo: generic:generic-foo:generic-foo-bar
> +# config-foo-debug: generic:generic-foo:debug:debug-foo
> +# is not a valid -debug variant
> +
>  # kernel.config files are build on the fly based on this config,
>  # the first arg is arch and variant, the second is a hierarchy of
>  # config options, lowest priority to highest
> diff --git a/redhat/configs/priority.rhel b/redhat/configs/priority.rhel
> index 0800c8cb9381..73ae53a8122e 100644
> --- a/redhat/configs/priority.rhel
> +++ b/redhat/configs/priority.rhel
> @@ -1,4 +1,18 @@
> -# config-variant=config:config:config
> +# Entries must be ordered as base and debug (if the debug variant exists)
> +# ie) config-variant-arch
> +#     config-variant-arch-debug (if the -debug variant exists)
> +
> +# Individual entries must be ordered as
> +# config-variant=config-1:config-2:config-3 in a descending order through
> +# the hierarchy
> +
> +# -debug variants must include the entirety of the base variant
> +# For example,
> +#
> +# config-foo: generic:generic-foo:generic-foo-bar
> +# config-foo-debug: generic:generic-foo:debug:debug-foo
> +# is not a valid -debug variant
> +
>  # kernel.config files are build on the fly based on this config,
>  # the first arg is arch and variant, the second is a hierarchy of
>  # config options, lowest priority to highest
> -- 
> GitLab
> _______________________________________________
> kernel mailing list -- [email protected]
> To unsubscribe send an email to [email protected]
> Fedora Code of Conduct: 
> https://docs.fedoraproject.org/en-US/project/code-of-conduct/
> List Guidelines: https://fedoraproject.org/wiki/Mailing_list_guidelines
> List Archives: 
> https://lists.fedoraproject.org/archives/list/[email protected]

-- 
[]'s
Herton
_______________________________________________
kernel mailing list -- [email protected]
To unsubscribe send an email to [email protected]
Fedora Code of Conduct: 
https://docs.fedoraproject.org/en-US/project/code-of-conduct/
List Guidelines: https://fedoraproject.org/wiki/Mailing_list_guidelines
List Archives: 
https://lists.fedoraproject.org/archives/list/[email protected]

Reply via email to