STYLE: drop 'getopt' in favour of hand-rolled option parsing

- improves flexibility and allows more consistent long options
This commit is contained in:
Mark Olesen 2010-04-09 16:55:47 +02:00
parent a55ce8eeba
commit f7b0b7ca71
4 changed files with 259 additions and 276 deletions

View File

@ -31,35 +31,36 @@
# Bugs
# -solution singularity not handled
#------------------------------------------------------------------------------
Script=${0##*/}
toolsDir=${0%/*}/tools
PROGDIR=`dirname $0`
PROGNAME=`basename $0`
DBFILE=${PROGNAME}.db
usage() {
while [ "$#" -ge 1 ]; do echo "$1"; shift; done
cat <<USAGE
printUsage() {
cat <<USAGE
$PROGNAME - extracts xy files from OpenFOAM logs.
Usage: $Script [OPTIONS] <log>
-list lists but does not extract
-n create single column files with the extracted data only
-quiet quiet operation
-help print the usage
Usage: $PROGNAME [-n][-s] <log>
extracts xy files from log
$PROGNAME -l <log>
lists but does not extract
$PROGNAME -h
for a help message
$Script - extracts xy files from OpenFOAM logs.
USAGE
exit 1
}
#------------------------------------------------------------------------------
printHelp() {
printUsage
cat <<LABHELP
cat <<HELP
-----------------------------------------------------------------------------
The default is to extract for all the 'Solved for' variables the initial
residual, the final residual and the number of iterations. Additionally, a
(user editable) database is used to extract data for standard non-solved for
variables like Courant number, and execution time.
$PROGNAME -l lists all the possible variables without extracting them.
$Script -l lists all the possible variables without extracting them.
The program will generate and run an awk script which writes a set of files,
logs/<var>_<subIter>, for every <var> specified, for every occurrence inside
@ -79,7 +80,7 @@ separated with '/' :
Column 2 is the extended regular expression (egrep) to select the line.
Column 3 is the string (fgrep) to select the column inside the line.
The value taken will be the first (non-space)word after this column.
The database ($PROGNAME.db) will taken from these locations:
The database ($Script.db) will taken from these locations:
.
$HOME/.OpenFOAM/$WM_PROJECT_VERSION
@ -87,61 +88,97 @@ The database ($PROGNAME.db) will taken from these locations:
$WM_PROJECT_INST_DIR/site/$WM_PROJECT_VERSION
$WM_PROJECT_INST_DIR/site
$WM_PROJECT_DIR/etc
$PROGDIR/tools
$toolsDir
Option -s suppresses the default information and only prints the extracted
Option -q suppresses the default information and only prints the extracted
variables.
-----------------------------------------------------------------------------
HELP
LABHELP
usage
}
# The various places to be searched:
for i in \
. \
$HOME/.OpenFOAM/$WM_PROJECT_VERSION \
$HOME/.OpenFOAM \
$WM_PROJECT_INST_DIR/site/$WM_PROJECT_VERSION \
$WM_PROJECT_INST_DIR/site \
$WM_PROJECT_DIR/etc \
$PROGDIR/tools \
;
timeName=Time
unset listOpt quietOpt
# parse options
while [ "$#" -gt 0 ]
do
if [ -r $i/$DBFILE ]
then
DBFILE="$i/$DBFILE"
case "$1" in
-h | -help)
printHelp
exit 0
;;
-n)
unset timeName
shift
;;
-l | -list)
listOpt=true
shift
;;
-q | -quiet | -s | -silent)
quietOpt=true
shift
;;
-*)
usage "unknown option: '$*'"
;;
*)
break
fi
;;
esac
done
# find the database file
DBFILE=$Script.db
[ -f $DBFILE ] || DBFILE=`foamEtcFile $Script.db` || DBFILE=$toolsDir/$Script.db
myEcho() {
if [ "$VERBOSE" ]
then
echo "$*"
fi
# need the database file
[ -f $DBFILE ] || {
echo "$Script: Cannot read database $DBFILE"
exit 1
}
# single logFile
if [ $# -eq 1 ]
then
LOG=$1
[ -r "$LOG" ] && [ -f "$LOG" ] || usage "Cannot read log $LOG"
else
usage
fi
myEcho()
{
[ "$quietOpt" = true ] || echo "$*"
}
# getSolvedVars logFile
# Prints names of all 'solved for' variables in the log file.
getSolvedVars() {
getSolvedVars()
{
fgrep ' Solving for ' $1 | fgrep ',' | sed -e 's/.* Solving for \([^,]*\)[,:].*/\1/' | sort -u
}
# getQueries dbFile queryName
# Gets regular expressions for a certain queryName from the database
getQueries() {
if [ ! -f "$1" ]
then
echo "Cannot find dbFile $1"
exit 1
fi
getQueries()
{
dbFile=$1
queryName=$2
LINEQ=`grep -v '^#' $1 | awk -F '/' "/$queryName/ {if (\"$queryName\" "'!= $1) next; print $2}'`
NUMQ=`grep -v '^#' $1 | awk -F '/' "/$queryName/ {if (\"$queryName\" "'!= $1) next; print $3}'`
[ -f "$dbFile" ] || {
echo "Cannot find dbFile $dbFile"
exit 1
}
LINEQ=`grep -v '^#' $dbFile | awk -F '/' "/$queryName/ {if (\"$queryName\" "'!= $1) next; print $2}'`
NUMQ=`grep -v '^#' $dbFile | awk -F '/' "/$queryName/ {if (\"$queryName\" "'!= $1) next; print $3}'`
#echo "For $queryName found line selection /$LINEQ/ , column selection /$NUMQ/" 1>&2
#if [ ! "$LINEQ" -o ! "$NUMQ" ]
@ -153,14 +190,16 @@ getQueries() {
# getDbQueryList dbFile
# Echoes list of possible queries
getDbQueryList() {
getDbQueryList()
{
grep -v '^#' $1 | grep '[^ \t]' | awk -F '/' '{print $1}'
}
# getSolveQueryList logFile
# Echoes list of queries from "solved for" variables in log file
getSolveQueryList() {
getSolveQueryList()
{
solvedVars=`getSolvedVars $1`
for var in $solvedVars
@ -174,7 +213,8 @@ getSolveQueryList() {
# getAllQueries dbFile logFile
# Gets all queries from database and from logfile
getAllQueries() {
getAllQueries()
{
#-- All solved for queries from log file
queries=`getSolveQueryList $2`
@ -208,107 +248,33 @@ getAllQueries() {
# Main
#-----------------------------
# sort arguments
TIMENAME='Time'
VERBOSE='yes'
LISTONLY=''
while getopts nslh flags
do
case $flags in
n)
TIMENAME=""
;;
h)
printHelp
exit 0
;;
s)
VERBOSE=""
;;
l)
LISTONLY='yes'
;;
\?)
printUsage
exit 1
;;
esac
done
# Shift options
shift `expr $OPTIND - 1`
if [ ! -f $DBFILE ]
if [ "$listOpt" = true ]
then
echo "$PROGNAME: Cannot read database $DBFILE"
exit 1
fi
if [ "$LISTONLY" ]
then
if [ $# -ne 1 ]
then
printUsage
exit 1
fi
LOG=$1;
if [ ! -r $LOG ]
then
echo "$PROGNAME: Cannot read log $LOG"
exit 1
fi
getAllQueries $DBFILE $LOG
exit 0
fi
if [ $# -ne 1 ]
then
printUsage
exit 1
fi
caseDir=.
outputDir=$caseDir/logs
CASEDIR=.
LOG=$1
if [ ! -r $LOG ]
then
echo "$PROGNAME: Cannot read log $LOG"
[ -d "$caseDir" ] || {
echo "$Script: Cannot read $caseDir"
exit 1
fi
}
QUERYNAMES=`getAllQueries $DBFILE $LOG`
if [ ! "$CASEDIR" ]
then
printUsage
exit 1
fi
if [ ! -d "$CASEDIR" ]
then
echo "$PROGNAME: Cannot read $CASEDIR"
exit 1
fi
if [ ! -f "$LOG" ]
then
echo "$PROGNAME: Cannot read log file $LOG"
exit 1
fi
#-- Make logs dir in case directory and put awk file there.
mkdir -p $CASEDIR/logs
AWKFILE=$CASEDIR/logs/$PROGNAME.awk
#
# Make logs dir in case directory and place awk file there
#
mkdir -p $outputDir
AWKFILE=$outputDir/$Script.awk
myEcho "Using:"
myEcho " log : $LOG"
myEcho " database : $DBFILE"
myEcho " awk file : $AWKFILE"
myEcho " files to : $CASEDIR/logs"
myEcho " files to : $outputDir"
myEcho ""
@ -316,22 +282,25 @@ myEcho ""
# Generate Awk program
#-----------------------------
#-- header
rm -f $AWKFILE 2> /dev/null
cat << AWK_CONTENTS > $AWKFILE
# header
BEGIN {
Iteration=0
resetCounters()
}
rm -f $AWKFILE; touch $AWKFILE
echo "BEGIN {" >> $AWKFILE
echo " Iteration=0" >> $AWKFILE
echo " resetCounters()" >> $AWKFILE
echo "}" >> $AWKFILE
# reset counters used for variable postfix
function resetCounters() {
AWK_CONTENTS
# ----------
echo "" >> $AWKFILE
echo "# reset counters used for variable postfix" >> $AWKFILE
echo "function resetCounters() {" >> $AWKFILE
for queryName in $QUERYNAMES
do
varName=${queryName}Cnt
echo " ${varName}=0" >> $AWKFILE
done
echo " # Reset counters for general Solving for extraction" >> $AWKFILE
echo " for (varName in subIter)" >> $AWKFILE
echo " {" >> $AWKFILE
@ -341,10 +310,9 @@ echo "}" >> $AWKFILE
echo "" >> $AWKFILE
cat <<LABEL >> $AWKFILE
cat << AWK_CONTENTS >> $AWKFILE
# Extract value after columnSel
function extract(inLine,columnSel,outVar,
a,b)
function extract(inLine,columnSel,outVar,a,b)
{
a=index(inLine, columnSel)
b=length(columnSel)
@ -352,71 +320,82 @@ function extract(inLine,columnSel,outVar,
gsub("[,:]","",outVar[1])
}
LABEL
AWK_CONTENTS
# ----------
#-- Generate code for iteration separator (increments 'Iteration')
#
# Code for iteration separator (increments 'Iteration')
#
getQueries $DBFILE 'Separator'
cat <<LABSEP >> $AWKFILE
#-- Iteration separator (increments 'Iteration')
cat << AWK_CONTENTS >> $AWKFILE
# Iteration separator (increments 'Iteration')
/$LINEQ/ {
Iteration++
resetCounters()
}
LABSEP
AWK_CONTENTS
# ----------
#-- Generate code for extracting Time
#
# Code for extracting Time
#
getQueries $DBFILE 'Time'
cat <<LABTIME >> $AWKFILE
#-- Time extraction (sets 'Time')
cat << AWK_CONTENTS >> $AWKFILE
# Time extraction (sets 'Time')
/$LINEQ/ {
extract(\$0, "$NUMQ", val)
Time=val[1]
}
LABTIME
AWK_CONTENTS
# ----------
#-- Generate code for singularity handling.
cat <<LABSING >> $AWKFILE
#-- Skip whole line with singularity variable
#
# Code for singularity handling.
#
cat << AWK_CONTENTS >> $AWKFILE
# Skip whole line with singularity variable
/solution singularity/ {
next;
}
LABSING
AWK_CONTENTS
# ----------
#-- Generate code for extracting solved for quantities
cat <<LABSOLVE >> $AWKFILE
#-- Extraction of any solved for variable
#
# Code for extracting solved for quantities
#
cat << AWK_CONTENTS >> $AWKFILE
# Extraction of any solved for variable
/Solving for/ {
extract(\$0, "Solving for ", varNameVal)
varName=varNameVal[1]
file=varName "_" subIter[varName]++
file="$CASEDIR/logs/" file
file="$outputDir/" file
extract(\$0, "Initial residual = ", val)
print $TIMENAME "\t" val[1] > file
print $timeName "\t" val[1] > file
varName=varNameVal[1] "FinalRes"
file=varName "_" subIter[varName]++
file="$CASEDIR/logs/" file
file="$outputDir/" file
extract(\$0, "Final residual = ", val)
print $TIMENAME "\t" val[1] > file
print $timeName "\t" val[1] > file
varName=varNameVal[1] "Iters"
file=varName "_" subIter[varName]++
file="$CASEDIR/logs/" file
file="$outputDir/" file
extract(\$0, "No Iterations ", val)
print $TIMENAME "\t" val[1] > file
print $timeName "\t" val[1] > file
}
LABSOLVE
AWK_CONTENTS
# ----------
#-- generate code to process queries
#
# Code to process queries
#
for queryName in $QUERYNAMES
do
getQueries $DBFILE $queryName
@ -424,11 +403,11 @@ do
then
counter=${queryName}Cnt
echo "#-- Extraction of $queryName" >> $AWKFILE
echo "# Extraction of $queryName" >> $AWKFILE
echo "/$LINEQ/ {" >> $AWKFILE
echo " extract(\$0, \"$NUMQ\", val)" >> $AWKFILE
echo " file=\"$CASEDIR/logs/${queryName}_\" ${counter}" >> $AWKFILE
echo " print $TIMENAME \"\\t\" val[1] > file" >> $AWKFILE
echo " file=\"$outputDir/${queryName}_\" ${counter}" >> $AWKFILE
echo " print $timeName \"\\t\" val[1] > file" >> $AWKFILE
echo " ${counter}++" >> $AWKFILE
echo "}" >> $AWKFILE
echo "" >> $AWKFILE

View File

@ -32,41 +32,70 @@
# Also removes consecutive blank lines from file.
#
#------------------------------------------------------------------------------
foamVersion=$WM_PROJECT_VERSION
usage() {
while [ "$#" -ge 1 ]; do echo "$1"; shift; done
cat<<USAGE
Usage: ${0##*/} [OPTION] <file1> ... <fileN>
options:
-v VER specifies the version to be written in the header
-h help
-version <ver> specifies the version to be written in the header
-help print the usage
Updates the header of application files and removes consecutive blank lines.
By default, writes current OpenFOAM version in the header.
An alternative version can be specified with the -v option.
An alternative version can be specified with the -version option.
USAGE
exit 1
}
#------------------------------------------------------------------------------
printHeader() {
# parse options
while [ "$#" -gt 0 ]
do
case "$1" in
-h | -help)
usage
;;
-v | -version)
[ "$#" -ge 2 ] || usage "'$1' option requires an argument"
version="$2"
shift 2
;;
-*)
usage "unknown option: '$*'"
;;
*)
break
;;
esac
done
# constant width for version - default to WM_PROJECT_VERSION
version=$(printf %-36s ${version:-$WM_PROJECT_VERSION})
[ $# -ge 1 ] || usage
#------------------------------------------------------------------------------
printHeader()
{
cat<<HEADER
/*--------------------------------*- C++ -*----------------------------------*\\
| ========= | |
| \\\\ / F ield | OpenFOAM: The Open Source CFD Toolbox |
| \\\\ / O peration | Version: ${foamVersion} |
| \\\\ / O peration | Version: $version |
| \\\\ / A nd | Web: www.OpenFOAM.org |
| \\\\/ M anipulation | |
\\*---------------------------------------------------------------------------*/
FoamFile
{
version 2.0;
format ${1};
class ${2};
object ${3};
format $1;
class $2;
object $3;
}
HEADER
}
@ -75,68 +104,40 @@ HEADER
#
# extract attribute '$1' from file '$2'
#
FoamFileAttribute() {
FoamFileAttribute()
{
sed -n -e 's/[ ;]*$//' -e "s/^ *$1 *//p" $2
}
#
# OPTIONS
# main
#
opts=$(getopt hv: $*)
if [ $? -ne 0 ]
then
echo "Aborting due to invalid option"
usage
fi
eval set -- '$opts'
while [ "$1" != "--" ]
do
case $1 in
-v)
foamVersion=$2
shift
;;
-h)
usage
;;
esac
shift
done
shift
[ $# -ge 1 ] || usage
# constant width for version
foamVersion=$(printf %-36s $foamVersion)
#
# MAIN
#
unset NOTE
tmpFile=FoamFile.tmp$$
for caseFile
do
if grep FoamFile $caseFile >/dev/null 2>&1
then
echo "Updating case file: $caseFile"
sed -n '/FoamFile/,/}/p' $caseFile > FoamFile.tmp
sed -n '/FoamFile/,/}/p' $caseFile > $tmpFile
FORMAT=$(FoamFileAttribute format FoamFile.tmp)
CLASS=$(FoamFileAttribute class FoamFile.tmp)
OBJECT=$(FoamFileAttribute object FoamFile.tmp)
# extract NOTE?
format=$(FoamFileAttribute format $tmpFile)
class=$(FoamFileAttribute class $tmpFile)
object=$(FoamFileAttribute object $tmpFile)
# extract note? - needs special handling
unset note
printHeader $FORMAT $CLASS $OBJECT $NOTE > FoamFile.tmp
sed '1,/}/d' $caseFile | sed '/./,/^$/!d' >> FoamFile.tmp
printHeader $format $class $object "$note" > $tmpFile
sed '1,/}/d' $caseFile | sed '/./,/^$/!d' >> $tmpFile
# use cat to avoid removing/replace soft-links
[ -s FoamFile.tmp ] && cat FoamFile.tmp >| $caseFile
rm -f FoamFile.tmp 2>/dev/null
[ -s $tmpFile ] && cat $tmpFile >| $caseFile
rm -f $tmpFile 2>/dev/null
else
echo " Invalid case file: $caseFile" 1>&2
fi
done
#------------------------------------------------------------------------------
#------------------------------------------------------------------ end-of-file

View File

@ -36,11 +36,11 @@ usage()
while [ "$#" -ge 1 ]; do echo "$1"; shift; done
cat<<USAGE
usage: $0 [OPTION]
usage: ${0##*/} [OPTION]
options:
-d sets up a default scheme on all schemes
-h this usage
-default sets up a default scheme on all schemes
-help print the usage
* quickly tests the tutorials and writes out the scheme/solver information
@ -48,6 +48,30 @@ USAGE
exit 1
}
#------------------------------------------------------------------------------
unset DEFAULT_SCHEMES
# parse options
while [ "$#" -gt 0 ]
do
case "$1" in
-h | -help)
usage
;;
-d | -default)
DEFAULT_SCHEMES=true
shift
;;
-*)
usage "unknown option: '$*'"
;;
*)
break
;;
esac
done
setDefaultFvSchemes()
{
@ -98,6 +122,7 @@ done
[ -f "$MAIN_CONTROL_DICT" ] || usage "main controlDict not found"
TUTORIALS_DIR=.
TEST_RUN_DIR=../tutorialsTest
FV_SCHEMES=\
@ -113,30 +138,7 @@ SCHEMES_FILE="FvSchemes"
SCHEMES_TEMP="FvSchemes.temp"
SOLVERS_FILE="FvSolution"
SOLVERS_TEMP="FvSolution.temp"
DEFAULT_SCHEMES=0
#
# OPTIONS
#
OPTS=`getopt hd $*`
if [ $? -ne 0 ]
then
usage "Aborting due to invalid option"
fi
eval set -- "$OPTS"
while [ $1 != -- ]
do
case $1 in
-d)
DEFAULT_SCHEMES=1
;;
-h)
usage
;;
esac
shift
done
shift
#
# MAIN
@ -182,7 +184,7 @@ do
${CD}.org > ${CD}
done
if [ $DEFAULT_SCHEMES = 1 ]
if [ "$DEFAULT_SCHEMES" = true ]
then
echo "Modifying the fvSchemes to contain only default schemes"
for FV_SC in `find . -name fvSchemes`
@ -209,8 +211,7 @@ do
echo "$APP: " | tr -d "\n" >> $SOLVERS_FILE
for ST in $FV_SCHEMES
do
rm $SCHEMES_TEMP > /dev/null 2>&1
rm $SOLVERS_TEMP > /dev/null 2>&1
rm $SCHEMES_TEMP $SOLVERS_TEMP > /dev/null 2>&1
echo " ${ST}" >> $SCHEMES_FILE
for LOG in `find ${APP} -name "log.${APP}"`
do

View File

@ -20,32 +20,34 @@ USAGE
exit 1
}
# -----------------------------------------------------------------------------
unset timeOpt
OPTS=`getopt hl $*`
[ $? -eq 0 ] || usage "Aborting due to invalid option"
eval set -- "$OPTS"
while [ $1 != -- ]
# parse options
while [ "$#" -gt 0 ]
do
case $1 in
-l)
timeOpt="-latestTime"
;;
-h)
case "$1" in
-h | -help)
usage
;;
-l | -latestTime)
timeOpt="-latestTime"
shift
;;
*)
usage "unknown option/argument: '$*'"
;;
esac
shift
done
shift
sample $timeOpt
SDIR="sets"
SDIR=sets
LSDIR=`ls $SDIR | head -1`
EXAMPLE_FILE=`ls -1 $SDIR/${LSDIR}/* | head -1`
FS=`basename $EXAMPLE_FILE | cut -d_ -f2-`
for d in $SDIR/*
do
cat ${d}/cone25_${FS} ${d}/cone55_${FS} ${d}/base_${FS} > ${d}/biconic_${FS}