On 7/16/20 12:20 PM, Herton R. Krzesinski wrote:
> On Thu, Jul 16, 2020 at 03:20:11PM -0000, GitLab Bridge on behalf of prarit 
> wrote:
>> From: Prarit Bhargava <[email protected]>
>>
> 
> Hi Prarit, on a quick read I noticed some minor typos/inconsistencies below.
> 

Whoops.  I had been staring at this so long I had just missed that.  Thanks.
I'll fix in v2.

P.

>> evaluate_configs is a tool that verifies the CONFIG setting heirarchy for
> 
> typo: hierarchy
> 
>> 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_NUMA output, da1 is not present
>> in the priority.rhel file and is marked with an 'X'.
> 
> You show an example of CONFIG_HEADER_TEST but mentions CONFIG_NUMA here.
> 
>>
>> The -x option can be used to evaluate all the CONFIGs by executing, for
>> example
>>
> 
> You mention -x option here, but seems the correct option is -f. Seems you 
> forgot
> to rename it as well on documentation and scripts below.
> 
> The same problems here in the commit message are on the 
> README.evaluate_configs
> below.
>  
>> |# 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
>>
>> 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..81bd44e2ac7e
>> --- /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_NUMA 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 -x 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: (heirarchy) 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..1a45a29f7d6a 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]"
>> +    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: (heirarchy) $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
>> +    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.
>> +
>> +    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]
> 
_______________________________________________
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