Skip to content

Commit

Permalink
feat: Rewrote rconfig to support INI files.
Browse files Browse the repository at this point in the history
  • Loading branch information
takusuman committed Dec 16, 2023
1 parent febeeb7 commit aeb6a57
Show file tree
Hide file tree
Showing 2 changed files with 67 additions and 23 deletions.
73 changes: 57 additions & 16 deletions build-system/internals/helpers/helpers.shi
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,50 @@
# Copyright (c) 2023 Pindorama
# Luiz Antônio Rangel
# SPDX-Licence-Identifier: NCSA
#
# "'Liberdade, Igualdade, Fraternidade',
# é o seguinte: se tem Liberdade, tem que
# ter Igualdade, Amor e Fraternidade [...]"

# Make everyone aware we're running from BUILD_KSH.
export readonly BUILD_KSH=true

# Reads INI configuration files, now a boilerplate function
# to dotini/inicompat --- and, in case of using
# GNU's Broken-Again Shell, it does a coarse conversion of
# the INI file to a simple Shell-based configuration file
# format.
function rconfig {
file="$1"

if [[ -z $BASH && -n $KSH_VERSION ]]; then
# Load the .ini configuration file as
# a compound variable to the memory.
# Simple as that.
eval conf=$(dotini "$file")
inicompat conf
elif [[ -n $BASH ]]; then # BASH
cat "$1" | \
for (( ;; )); do
if read line; then
if [[ "$line" =~ \[.*\] ]] || [[ "$line" =~ ^$ ]] \
|| [[ "$line" =~ '^[#;].*$' ]]; then
continue
else
keyval="$(printf '%s' "$line" \
| sed 's/^\(.*\)[#;].*/\1/;')"
identifier="${keyval%%=*}"
value="${keyval##*=}"
[[ "$keyval" =~ ^$ ]] && continue
eval $(printf '%s='\''%s'\''' $identifier "$value")
fi
else
break
fi
done
fi
}

# This function parses .INI files into a compound variable that can be used
# inside the script via eval.
# For example:
Expand Down Expand Up @@ -102,7 +142,17 @@ function dotini {
# If there is not a section, it will only declare the INI
# variable and its value on the compound variable.
if [[ ! -n $formatted_section ]]; then
printf '%s="%s" ' \
# Using a apostrophe instead of quotations marks
# because, apart from the fact that it works as a
# micro-optimization --- since the shell will be
# treating its contents as vulgar strings instead of
# trying to interpret what is inside them ---, also
# prevents globbing of strings.
# The only thing that it doesn't prevents,
# unfortunately, is the abuse of subshells or malicious
# substitutions, but I do not think this can be a
# problem here.
printf '%s='\''%s'\'' ' \
"${confline[0]}" "${confline[1]}"

# Continue to the next line.
Expand All @@ -111,7 +161,7 @@ function dotini {

# If it there's a section and the value declaration was already
# parsed, return it as a associative array declaration.
printf '[%s]+=([%s]=%s) ' \
printf '[%s]+=([%s]='\''%s'\'') ' \
$formatted_section "${confline[0]}" "${confline[1]}"

# Clean confline[] array.
Expand All @@ -132,8 +182,6 @@ function dotini {
#
# NOTE: See dotini()'s first "FIXME" and then implement a way to do it.
function inicompat {
set -x

nameref inirecord=$1
integer s k
typeset -a sections
Expand All @@ -145,11 +193,11 @@ function inicompat {

section=${sections[s]}
confkeys=( ${!inirecord[$section][@]} )
print -v confkeys

for (( k=0; k < ${#confkeys[@]}; k++ )); do
confkey=${confkeys[$k]}
confval="${inirecord[$section][$confkey]}"

eval $(printf '%s=%s' $confkey "$confval")
unset confkey confval
done
Expand Down Expand Up @@ -200,6 +248,10 @@ function record {

# Using the good old Bourne function prototype because it permits that the
# function caller name "escapes" into it.
# This is broken in GNU's Broken-Again Shell --- well, maybe I'm repeating
# this joke too many times, but Bash lives up to its nickname --- but this
# is no problem for now since Bash doesn't support compound variables,
# just associative arrays, so both "map" and "record" can be the same to Bash.
__record() {
# "London calling to the faraway towns...
# But it wasn't my love...
Expand All @@ -224,17 +276,6 @@ __record() {
printf "$format" "$identifier" "$variable" "$value"
}

# Reads simple Shell-based configuration files.
# "#" is used for comments, and white spaces are ignored for read(1).
# Could be better written, sed did not need to be here.

This comment has been minimized.

Copy link
@takusuman

takusuman Dec 16, 2023

Author Member

First, store it in a cache:

file="$1"
integer nl
typeset -a confbuf
for ((nl=0 ;; nl++)); do
  if read line; then
    confbuf[$nl]="$line"
  else
    break
  fi
done < "$file"

Then, read and parse it:

integer l
for ((l=0; l<${#confbuf[@]}; l++)); do
  if [[ "${confbuf[$l]}" =~ (^$) ]] \
     ||  [[ "${confbuf[$l]}" =~ (^\#.*$) ]]; then
     continue
  else
      printf '%s' "${confbuf[$l]}" | IFS='=' read identifier value
      eval $(printf '%s=%s' $identifier "$value")
  fi
done

This, of course, just catches plain comments, not comments in lines along the key-value declaration, but I think this can be a good base for anyone wanting to read configuration files in KornShell or GNU Bash.

# Deprecated in favour of dotini(), see above.
function rconfig {
(sed '/#/d; /^$/d' "$1") \
| while IFS='=' read identifier value; do
eval $(printf '%s=%s' $identifier "$value")
done
}

# Luiz' stupid (re)match.
# It's my attempt on mimicking BASH_REMATCH functionality
# on pretty much any shell. Made it for using on dotini(),
Expand Down
17 changes: 10 additions & 7 deletions build.ksh
Original file line number Diff line number Diff line change
Expand Up @@ -9,35 +9,38 @@ progname="${0##*/}"
progdir="$(cd "$(dirname "$progname")"; pwd -P)"
trash="$(mktemp -d /tmp/CopaBuild.XXXXXX)"

# Immediatly source and run the platform checks before doing anything else.
. "$progdir/build-system/tasks/platform_checks.ksh"; platform_checks

# Internal build system functions
. "$progdir/build-system/internals/helpers/helpers.shi"
. "$progdir/build-system/internals/helpers/posix-alt.shi"

# Task files
. "$progdir/build-system/tasks/platform_checks.ksh"
. "$progdir/build-system/tasks/check_dependencies.ksh"
. "$progdir/build-system/tasks/disk_managenment.ksh"
. "$progdir/build-system/tasks/get_source-code.ksh"
. "$progdir/build-system/tasks/build_all.ksh"

. "$progdir/build-system/tasks/finish.ksh"

rconfig "$progdir/build-system/machine.conf"
rconfig "$progdir/build-system/paths.conf"
rconfig "$progdir/build-system/machine.ini"

map dtime initial "$(date +'%Hh%Mmin on %B %d, %Y')"

platform_checks
check_elevate_method
check_dependencies
create_disk "$DISK_BLOCK"
populate
get_sources sources.txt sources.sha256
build cross-tools "base/kernel-headers" "dev/GNUBinutils" \
"dev/GNUcc" "base/LibC" "dev/GNUcc"
build cross-tools cross/mussel
#build cross-tools "base/kernel-headers" "dev/GNUBinutils" \
# "dev/GNUcc" "base/LibC" "dev/GNUcc"

#build tools "base/kernel-headers" "dev/GNUBinutils" \
# "dev/GNUcc" "base/LibC" "dev/GNUcc"

#build base "base/kernel-headers" "dev/GNUBinutils" \
# "dev/GNUcc" "base/LibC" "dev/GNUcc"

build close
finish

0 comments on commit aeb6a57

Please sign in to comment.