source: branches/libIGCM_MPI_OpenMP/libIGCM_card/libIGCM_card.ksh @ 494

Last change on this file since 494 was 475, checked in by sdipsl, 13 years ago
  • Better error handling within libGCM
  • Pre requisite to have more robust post-processing workflow
  • Improve verbosity to help users identify problem
  • Cosmetic
  • backward compatible
  • Property licence set to
    The following licence information concerns ONLY the libIGCM tools
    ==================================================================

    Copyright © Centre National de la Recherche Scientifique CNRS
    Commissariat à l'Énergie Atomique CEA

    libIGCM : Library for Portable Models Computation of IGCM Group.

    IGCM Group is the french IPSL Global Climate Model Group.

    This library is a set of shell scripts and functions whose purpose is
    the management of the initialization, the launch, the transfer of
    output files, the post-processing and the monitoring of datas produce
    by any numerical program on any plateforme.

    This software is governed by the CeCILL license under French law and
    abiding by the rules of distribution of free software. You can use,
    modify and/ or redistribute the software under the terms of the CeCILL
    license as circulated by CEA, CNRS and INRIA at the following URL
    "http://www.cecill.info".

    As a counterpart to the access to the source code and rights to copy,
    modify and redistribute granted by the license, users are provided only
    with a limited warranty and the software's author, the holder of the
    economic rights, and the successive licensors have only limited
    liability.

    In this respect, the user's attention is drawn to the risks associated
    with loading, using, modifying and/or developing or reproducing the
    software by the user in light of its specific status of free software,
    that may mean that it is complicated to manipulate, and that also
    therefore means that it is reserved for developers and experienced
    professionals having in-depth computer knowledge. Users are therefore
    encouraged to load and test the software's suitability as regards their
    requirements in conditions enabling the security of their systems and/or
    data to be ensured and, more generally, to use and operate it in the
    same conditions as regards security.

    The fact that you are presently reading this means that you have had
    knowledge of the CeCILL license and that you accept its terms.
  • Property svn:keywords set to Revision Author Date
File size: 11.9 KB
Line 
1#!/bin/ksh
2
3#**************************************************************
4# Author: Patrick Brockmann
5# Contact: Patrick.Brockmann__at__cea.fr
6# $Revision::                                          $ Revision of last commit
7# $Author::                                            $ Author of last commit
8# $Date::                                              $ Date of last commit
9# IPSL (2006)
10#  This software is governed by the CeCILL licence see libIGCM/libIGCM_CeCILL.LIC
11#
12#**************************************************************
13
14#==================================================
15# The documentation of this file can be automatically generated
16# if you use the prefix #D- for comments to be extracted.
17# Extract with command: cat lib* | grep "^#D-" | cut -c "4-"
18#==================================================
19 
20#D-#==================================================================
21#D-libIGCM_card
22#D-This ksh library handles extraction of information from configuration file
23#D-called "card" file (en français fichier "carte").
24#D-All function described bellow must be prefixed by IGCM_card.
25#D-A card file is organized as follows :
26#D- ---------------------
27#D-[Messages]
28#D-Option1= "Hello Earth"
29#D-Option2= "Hello Mars"
30#D-
31#D-# My comments
32#D-[Recipes]
33#D-Cake= "file1.doc"
34#D-Starter= "file2.doc"
35#D-
36#D-[ColorValues]
37#D-Red= 120
38#D-Blue= 230
39#D-Green= 178
40#D-
41#D-[Couples]
42#D-List1=   (up, down), \
43#D-         (humid, dry), \
44#D-         (hot, cold), \
45#D-         (far, close)
46#D-List2=   (ice, fire, air, water)
47#D- ---------------------
48#D-
49
50#D-#==================================================================
51#D-function IGCM_card_PrintOption
52#D-* Purpose: Print an option from a given file.card and section
53#D-* Usage: IGCM_card_PrintOption file.card section option
54#D-* Only used by IGCM_card_Test.ksh
55#D-
56function IGCM_card_PrintOption
57{
58    IGCM_debug_PushStack "IGCM_card_PrintOption" $@
59    if ( [ -r "$1" ] && [ -f "$1" ] ) ; then
60        gawk -f ${libIGCM}/libIGCM_card/IGCM_card_PrintOption.awk "$@"
61    else
62        echo
63        IGCM_debug_Print 1 "--Error--> IGCM_card_PrintOption $@"
64        IGCM_debug_Print 1 "           $1 is not readable"
65        IGCM_debug_Exit "IGCM_card_PrintOption"
66    fi
67    IGCM_debug_PopStack "IGCM_card_PrintOption"
68}
69
70#D-#==================================================================
71#D-function IGCM_card_PrintSection
72#D-* Purpose: Print all options from a given file.card and section
73#D-* Usage: IGCM_card_PrintSection file.card section
74#D-* Only used by IGCM_card_Test.ksh
75#D-
76function IGCM_card_PrintSection
77{
78    IGCM_debug_PushStack "IGCM_card_PrintSection" $@
79    if ( [ -r "$1" ] && [ -f "$1" ] ) ; then
80        gawk -f ${libIGCM}/libIGCM_card/IGCM_card_PrintSection.awk -- "$@"
81    else
82        IGCM_debug_Print 1 "--Error--> IGCM_card_PrintSection $@"
83        IGCM_debug_Print 1 "           $1 is not readable"
84        IGCM_debug_Exit "IGCM_card_PrintSection"
85    fi
86    IGCM_debug_PopStack "IGCM_card_PrintSection"
87}
88
89#D-#==================================================================
90#D-function IGCM_card_DefineVariableFromOption
91#D-* Purpose: Define a variable from a given file.card, section and option
92#D-*          Variable name is automatically defined as file_section_option
93#D-* Usage: IGCM_card_DefineVariableFromOption file.card section option
94#D-
95function IGCM_card_DefineVariableFromOption
96{
97    IGCM_debug_PushStack "IGCM_card_DefineVariableFromOption" $@
98    if ( [ -r "$1" ] && [ -f "$1" ] ) ; then
99        # Get basename of card file ($1)
100        typeset name1=${1##*/}
101        # Build name of variable as $1_$2_$3 (cardname_Section_Option)
102        typeset name=${name1%%.*}_${2}_${3}
103        typeset value=$( gawk -f ${libIGCM}/libIGCM_card/IGCM_card_PrintOption.awk -- "$@" )
104
105        # Only if a section is missing we exit the job.
106        # We must allow missing option to keep backward compatibilty.
107        if [ "${value}" = "Error: Section not found" ] ; then
108            echo
109            IGCM_debug_Print 1 "Error with readding of ${name} variable in ${1}."
110            IGCM_debug_Print 1 "Error: Section ${2} not found"
111            IGCM_debug_Exit
112            IGCM_debug_Verif_Exit
113        fi
114        eval ${name}=${value}
115    else
116        echo
117        IGCM_debug_Print 1 "--Error--> IGCM_card_DefineVariableFromOption"
118        IGCM_debug_Print 1 "--Error--> $1 is not readable"
119        IGCM_debug_Exit "IGCM_card_DefineVariableFromOption"
120        IGCM_debug_Verif_Exit
121    fi
122    IGCM_debug_PopStack "IGCM_card_DefineVariableFromOption"
123}
124
125#D-#==================================================================
126#D-function IGCM_card_DefineArrayFromOption
127#D-* Purpose: Define an array variable from a given file.card, section and option
128#D-*          Array variable is automatically defined as file_section_option
129#D-* Usage: IGCM_card_DefineArrayFromOption file.card section option
130#D-
131function IGCM_card_DefineArrayFromOption
132{
133    IGCM_debug_PushStack "IGCM_card_DefineArrayFromOption" $@
134    if ( [ -r "$1" ] && [ -f "$1" ] ) ; then
135        # Get basename of card file ($1)
136        typeset name1=${1##*/}
137        # Build name of array as $1_$2_$3 (cardname_Section_Option)
138        typeset name=${name1%%.*}_${2}_${3}
139        eval unset ${name}
140        eval ${name}[0]=${NULL_STR}
141        set +A ${name} -- $( gawk -f ${libIGCM}/libIGCM_card/IGCM_card_PrintOption.awk -- "$@" | gawk -- 'BEGIN {FS="[() ,]+"} {for (i=2; i <= NF-1; i++) printf("%s ",$i)}' )
142    else
143        echo
144        IGCM_debug_Print 1 "--Error--> IGCM_card_DefineArrayFromOption $@"
145        IGCM_debug_Print 1 "           $1 is not readable"
146        IGCM_debug_Exit "IGCM_card_DefineArrayFromOption"
147    fi
148    IGCM_debug_PopStack "IGCM_card_DefineArrayFromOption"
149}
150
151#D-#==================================================================
152#D-function IGCM_card_DefineArrayFromSection
153#D-* Purpose: Define an array variable from a given file.card and section
154#D-*          Array variable is automatically defined as file_section
155#D-* Usage: IGCM_card_DefineArrayFromSection file.card section
156#D-
157function IGCM_card_DefineArrayFromSection
158{
159    IGCM_debug_PushStack "IGCM_card_DefineArrayFromSection" $@
160    if ( [ -r "$1" ] && [ -f "$1" ] ) ; then
161        # Get basename of card file ($1)
162        typeset name1=${1##*/}
163        # Build name of array as $1_$2 (cardname_Section)
164        typeset name=${name1%%.*}_${2}
165        eval unset ${name}
166        eval ${name}[0]=${NULL_STR}
167        set +A ${name} -- $( gawk -f ${libIGCM}/libIGCM_card/IGCM_card_PrintSection.awk -- "$@" )
168        if [ "$( eval echo \${${name}[@]} )" = "Error: Section not found" ] ; then
169            echo
170            IGCM_debug_Print 1 "Error with readding of ${name} variable in ${1}."
171            IGCM_debug_Print 1 "Error: Section ${2} not found"
172            IGCM_debug_Exit
173            IGCM_debug_Verif_Exit
174        fi
175    else
176        IGCM_debug_Print 1 "--Error--> IGCM_card_DefineArrayFromSection $@"
177        IGCM_debug_Print 1 "           $1 is not readable"
178        IGCM_debug_Exit "IGCM_card_DefineArrayFromSection"
179    fi
180    IGCM_debug_PopStack "IGCM_card_DefineArrayFromSection"
181}
182
183#D-#==================================================================
184#D-function IGCM_card_WriteOption
185#D-* Purpose: Write an option in a given file.card and section
186#D-* Usage: IGCM_card_WriteOption file.card section newvalue
187#D-* Examples: IGCM_card_WriteOption file.card Recipes Red 150
188#D-            IGCM_card_WriteOption file.card Messages Option2 '"Hello Mercure"'
189#D-            IGCM_card_WriteOption file.card Messages ListVal1 '( 1, 2, 3 )'
190#D-            listname="(Sebastien, Martial, Patrick)"
191#D-            IGCM_card_WriteOption NewTestFile.card Messages ListVal2 "${listname}"
192#D-
193function IGCM_card_WriteOption
194{
195    IGCM_debug_PushStack "IGCM_card_WriteOption" $@
196    if ( [ -r "$1" ] && [ -w "$1" ]  && [ -f "$1" ] ) ; then
197        typeset tmpfile=tmpfile_$$
198        ( IGCM_card_PrintOption "$1" "$2" "$3" | grep "not found" ) > ${tmpfile}
199        if [ $( cat ${tmpfile} | wc -l ) -gt 0 ] ; then
200            echo "-------------------------------------------"
201            echo "!!! Problem with IGCM_card_WriteOption !!!"
202            echo "Try to write : " $@
203            echo "You have to correct some script." 
204            echo "We won't do anything else !"
205            exit 1
206        fi
207        \rm ${tmpfile}
208
209        # The tmpfile uses now the real path of the card to be modified,
210        # not just a local tmpfile with PID.
211        tmpfile=$1_mutex_$$
212
213        IGCM_card_CheckConflict $1
214
215        # Do the job
216        ( gawk -f ${libIGCM}/libIGCM_card/IGCM_card_WriteOption.awk -- "$@" 2> /dev/null ) > ${tmpfile}
217
218        cp $1 $1.bak
219        mv ${tmpfile} $1
220
221    else
222        echo
223        IGCM_debug_Print 1 "--Error--> IGCM_card_WriteOption $@"
224        IGCM_debug_Print 1 "           $1 is not readable or not writable"
225        IGCM_debug_Exit "IGCM_card_WriteOption"
226    fi
227    IGCM_debug_PopStack "IGCM_card_WriteOption"
228}
229
230function IGCM_card_CheckConflict
231{
232    IGCM_debug_PushStack "IGCM_card_CheckConflict" $@
233
234    typeset isleep tmpfiles
235
236    # Watch for possible conflics : Check for other tmpfiles.
237    set +A tmpfiles -- $( ls $1_mutex_[0-9]* 2>/dev/null )
238    ((isleep=0))
239    while [ ${#tmpfiles[@]} -gt 0 ] ; do
240        echo "Conflict between two processes working on " $1 "!!!" ${tmpfiles[@]}
241        sleep 1
242        ((isleep=isleep+1))
243        if [ isleep -gt 20 ] ; then
244            echo "Too many loops waiting for other process working on " $1 ". We continue."
245            echo "You should see if one process of your run or post-treatment may have terminated suddenly."
246            echo "Afer, you should erase this(those) file(s) : " ${tmpfiles[@]}
247# Send a mail to USER ??
248            break ;
249        fi
250        unset tmpfiles
251        set +A tmpfiles -- $( ls $1_mutex_[0-9]* 2>/dev/null )
252    done
253
254    IGCM_debug_PopStack "IGCM_card_CheckConflict"
255}
256
257#D-#==================================================================
258#D-function IGCM_card_WriteArrayOption
259#D-* Purpose: Write an array option a given file.card and section
260#D-* Usage: IGCM_card_WriteArrayOption file.card section option newarray
261#D-* Examples: set -A MyArray -- 1 2 3
262#D-            IGCM_card_WriteArrayOption file.card Recipes List MyArray
263#D-
264function IGCM_card_WriteArrayOption
265{
266    IGCM_debug_PushStack "IGCM_card_WriteArrayOption" $@
267
268    if ( [ -r "$1" ] && [ -w "$1" ]  && [ -f "$1" ] ) ; then
269        typeset tmpfile=tmpfile_$$
270        if [ X"${4}" != X"" ]; then
271            tab=$4
272            IGCM_card_WriteOption $1 $2 $3 '('$( eval echo \${${tab}[@]} | sed -e 's/ /,/g' )')'
273        else
274            IGCM_card_WriteOption $1 $2 $3 '()'
275        fi
276    else
277        echo
278        IGCM_debug_Print 1 "--Error--> IGCM_card_WriteArrayOption $@"
279        IGCM_debug_Print 1 "           $1 is not readable or not writable"
280        IGCM_debug_Exit "IGCM_card_WriteArrayOption"
281    fi
282    IGCM_debug_PopStack "IGCM_card_WriteArrayOption"
283}
284
285#D-#==================================================================
286#D-function IGCM_card_Check
287#D-* Purpose: Check the present file by comparison with a reference file
288#D-* Usage: IGCM_card_Check
289#D-
290function IGCM_card_Check
291{
292    IGCM_debug_PushStack "IGCM_card_Check" 
293#---------------------
294    if [ ! -n "${libIGCM}" ] ; then
295        echo "Check libIGCM_card ...........................................[ FAILED ]"
296        echo "--Error--> libIGCM variable is not defined"
297        IGCM_debug_Exit "IGCM_card_Check"
298    fi
299
300#---------------------
301    whence -v gawk > /dev/null 2>&1
302    if [ ! $? -eq 0 ] ; then
303        echo "Check libIGCM_card ...........................................[ FAILED ]"
304        echo "--Error--> gawk command is not defined"
305        IGCM_debug_Exit "IGCM_card_Check"
306    fi
307
308#---------------------
309    ${libIGCM}/libIGCM_card/IGCM_card_Test.ksh > IGCM_card_Test.ref.failed 2>&1
310    sleep 2
311
312    if diff IGCM_card_Test.ref.failed ${libIGCM}/libIGCM_card/IGCM_card_Test.ref > /dev/null 2>&1 ; then
313        echo "Check libIGCM_card ...............................................[ OK ]"
314        IGCM_sys_Rm IGCM_card_Test.ref.failed
315    else
316        echo "Check libIGCM_card ...........................................[ FAILED ]"
317        echo "--Error--> Execution of ${libIGCM}/libIGCM_card/IGCM_card_Test.ksh"
318        echo "           has produced the file IGCM_card_Test.ref.failed"
319        echo "           Please analyse differences with the reference file by typing:"
320        echo "           diff IGCM_card_Test.ref.failed ${libIGCM}/libIGCM_card/IGCM_card_Test.ref"
321        echo "           Report errors to the author: Patrick.Brockmann@cea.fr"
322        IGCM_debug_Exit "IGCM_card_Check"
323    fi
324
325#---------------------
326    IGCM_debug_PopStack "IGCM_card_Check" 
327}
Note: See TracBrowser for help on using the repository browser.