source: trunk/libIGCM/libIGCM_card/libIGCM_card.ksh @ 1135

Last change on this file since 1135 was 1135, checked in by sdipsl, 10 years ago
  • Cosmetics. It was backward compatible but it's nicer like this
  • 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: 12.6 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      elif [ "${value}" = "Error: Option not found" ] ; then
114         eval ${name}=${NULL_STR}
115      else
116        eval ${name}=${value}
117      fi
118      echo ${value}
119  else
120    echo
121    IGCM_debug_Print 1 "--Error--> IGCM_card_DefineVariableFromOption"
122    IGCM_debug_Print 1 "--Error--> $1 is not readable"
123    IGCM_debug_Exit "IGCM_card_DefineVariableFromOption"
124    IGCM_debug_Verif_Exit
125  fi
126  IGCM_debug_PopStack "IGCM_card_DefineVariableFromOption"
127}
128
129#D-#==================================================================
130#D-function IGCM_card_DefineArrayFromOption
131#D-* Purpose: Define an array variable from a given file.card, section and option
132#D-*          Array variable is automatically defined as file_section_option
133#D-* Usage: IGCM_card_DefineArrayFromOption file.card section option
134#D-
135function IGCM_card_DefineArrayFromOption
136{
137  IGCM_debug_PushStack "IGCM_card_DefineArrayFromOption" $@
138  if ( [ -r "$1" ] && [ -f "$1" ] ) ; then
139    # Get basename of card file ($1)
140    typeset name1=${1##*/}
141    # Build name of array as $1_$2_$3 (cardname_Section_Option)
142    typeset name=${name1%%.*}_${2}_${3}
143    eval unset ${name}
144    eval ${name}[0]=${NULL_STR}
145    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)}' )
146  else
147    echo
148    IGCM_debug_Print 1 "--Error--> IGCM_card_DefineArrayFromOption $@"
149    IGCM_debug_Print 1 "           $1 is not readable"
150    IGCM_debug_Exit "IGCM_card_DefineArrayFromOption"
151  fi
152  IGCM_debug_PopStack "IGCM_card_DefineArrayFromOption"
153}
154
155#D-#==================================================================
156#D-function IGCM_card_DefineArrayFromSection
157#D-* Purpose: Define an array variable from a given file.card and section
158#D-*          Array variable is automatically defined as file_section
159#D-* Usage: IGCM_card_DefineArrayFromSection file.card section
160#D-
161function IGCM_card_DefineArrayFromSection
162{
163  IGCM_debug_PushStack "IGCM_card_DefineArrayFromSection" $@
164  if ( [ -r "$1" ] && [ -f "$1" ] ) ; then
165    # Get basename of card file ($1)
166    typeset name1=${1##*/}
167    # Build name of array as $1_$2 (cardname_Section)
168    typeset name=${name1%%.*}_${2}
169    eval unset ${name}
170    eval ${name}[0]=${NULL_STR}
171    set +A ${name} -- $( gawk -f ${libIGCM}/libIGCM_card/IGCM_card_PrintSection.awk -- "$@" )
172    #if [ "$( eval echo \${${name}[@]} )" = "Error: Section not found" ] ; then
173    #    echo
174    #    IGCM_debug_Print 1 "Error with readding of ${name} variable in ${1}."
175    #    IGCM_debug_Print 1 "Error: Section ${2} not found"
176    #    IGCM_debug_Exit
177    #    IGCM_debug_Verif_Exit
178    #fi
179    if [ "$( eval echo \${${name}[@]} )" = "Error: Section not found" ] ; then
180      echo
181      IGCM_debug_Print 1 "Warning with readding of ${name} variable in ${1}."
182      IGCM_debug_Print 1 "Warning: Section ${2} not found"
183      eval unset ${name}
184    fi
185  else
186    IGCM_debug_Print 1 "--Error--> IGCM_card_DefineArrayFromSection $@"
187    IGCM_debug_Print 1 "           $1 is not readable"
188    IGCM_debug_Exit "IGCM_card_DefineArrayFromSection"
189  fi
190  IGCM_debug_PopStack "IGCM_card_DefineArrayFromSection"
191}
192
193#D-#==================================================================
194#D-function IGCM_card_WriteOption
195#D-* Purpose: Write an option in a given file.card and section
196#D-* Usage: IGCM_card_WriteOption file.card section newvalue
197#D-* Examples: IGCM_card_WriteOption file.card Recipes Red 150
198#D-            IGCM_card_WriteOption file.card Messages Option2 '"Hello Mercure"'
199#D-            IGCM_card_WriteOption file.card Messages ListVal1 '( 1, 2, 3 )'
200#D-            listname="(Sebastien, Martial, Patrick)"
201#D-            IGCM_card_WriteOption NewTestFile.card Messages ListVal2 "${listname}"
202#D-
203function IGCM_card_WriteOption
204{
205  IGCM_debug_PushStack "IGCM_card_WriteOption" $@
206  if ( [ -r "$1" ] && [ -w "$1" ]  && [ -f "$1" ] ) ; then
207    typeset tmpfile=tmpfile_$$
208    ( IGCM_card_PrintOption "$1" "$2" "$3" | grep "not found" ) > ${tmpfile}
209    if [ $( cat ${tmpfile} | wc -l ) -gt 0 ] ; then
210      IGCM_debug_Print 1 "!!! Issue with IGCM_card_WriteOption !!!"
211      IGCM_debug_Print 1 "We tried to write : $@"
212      IGCM_debug_Exit "Must check that option $3 in section $2 exist in this file $1"
213      IGCM_debug_Verif_Exit
214    fi
215    \rm ${tmpfile}
216
217    # The tmpfile uses now the real path of the card to be modified,
218    # not just a local tmpfile with PID.
219    tmpfile=$1_mutex_$$
220
221    IGCM_card_CheckConflict $1
222
223    # Do the job
224    ( gawk -f ${libIGCM}/libIGCM_card/IGCM_card_WriteOption.awk -- "$@" 2> /dev/null ) > ${tmpfile}
225
226    cp $1 $1.bak
227    mv ${tmpfile} $1
228
229  else
230    echo
231    IGCM_debug_Print 1 "--Error--> IGCM_card_WriteOption $@"
232    IGCM_debug_Print 1 "           $1 is not readable or not writable"
233    IGCM_debug_Exit "IGCM_card_WriteOption"
234  fi
235  IGCM_debug_PopStack "IGCM_card_WriteOption"
236}
237
238#D-#==================================================================
239#D-function IGCM_card_CheckConflict
240#D-* Purpose: Check that a card is not in use by another process. If it is the case wait until it is not.
241#D-* Usage: IGCM_card_CheckConflict run.card
242#D-* Examples:
243#D-
244function IGCM_card_CheckConflict
245{
246  IGCM_debug_PushStack "IGCM_card_CheckConflict" $@
247  typeset isleep tmpfiles
248
249  # Watch for possible conflics : Check for other tmpfiles.
250  set +A tmpfiles -- $( ls $1_mutex_[0-9]* 2>/dev/null )
251  ((isleep=0))
252  while [ ${#tmpfiles[@]} -gt 0 ] ; do
253    echo "Conflict between two processes working on " $1 "!!!" ${tmpfiles[@]}
254    sleep 1
255    ((isleep=isleep+1))
256    if [ ${isleep} -gt 20 ] ; then
257      echo "Too many loops waiting for other process working on " $1 ". We continue."
258      echo "You should see if one process of your run or post-treatment may have terminated suddenly."
259      echo "Afer, you should erase this(those) file(s) : " ${tmpfiles[@]}
260      # Send a mail to USER ??
261      break ;
262    fi
263    unset tmpfiles
264    set +A tmpfiles -- $( ls $1_mutex_[0-9]* 2>/dev/null )
265  done
266
267  IGCM_debug_PopStack "IGCM_card_CheckConflict"
268}
269
270#D-#==================================================================
271#D-function IGCM_card_WriteArrayOption
272#D-* Purpose: Write an array option a given file.card and section
273#D-* Usage: IGCM_card_WriteArrayOption file.card section option newarray
274#D-* Examples: set -A MyArray -- 1 2 3
275#D-            IGCM_card_WriteArrayOption file.card Recipes List MyArray
276#D-
277function IGCM_card_WriteArrayOption
278{
279  IGCM_debug_PushStack "IGCM_card_WriteArrayOption" $@
280
281  if ( [ -r "$1" ] && [ -w "$1" ]  && [ -f "$1" ] ) ; then
282    typeset tmpfile=tmpfile_$$
283    if [ X"${4}" != X"" ]; then
284      tab=$4
285      IGCM_card_WriteOption $1 $2 $3 '('$( eval echo \${${tab}[@]} | sed -e 's/ /,/g' )')'
286    else
287      IGCM_card_WriteOption $1 $2 $3 '()'
288    fi
289  else
290    echo
291    IGCM_debug_Print 1 "--Error--> IGCM_card_WriteArrayOption $@"
292    IGCM_debug_Print 1 "           $1 is not readable or not writable"
293    IGCM_debug_Exit "IGCM_card_WriteArrayOption"
294  fi
295  IGCM_debug_PopStack "IGCM_card_WriteArrayOption"
296}
297
298#D-#==================================================================
299#D-function IGCM_card_Check
300#D-* Purpose: Check the present file by comparison with a reference file
301#D-* Usage: IGCM_card_Check
302#D-
303function IGCM_card_Check
304{
305  #---------------------
306  if [ ! -n "${libIGCM}" ] ; then
307    echo "Check libIGCM_card ...........................................[ FAILED ]"
308    echo "--Error--> libIGCM variable is not defined"
309    IGCM_debug_Exit "IGCM_card_Check"
310  fi
311
312  #---------------------
313  whence -v gawk > /dev/null 2>&1
314  if [ ! $? -eq 0 ] ; then
315    echo "Check libIGCM_card ...........................................[ FAILED ]"
316    echo "--Error--> gawk command is not defined"
317    IGCM_debug_Exit "IGCM_card_Check"
318  fi
319
320  #---------------------
321  # No need to remove timestamps here
322  diff ${libIGCM}/libIGCM_card/IGCM_card_Test.ref <(${libIGCM}/libIGCM_card/IGCM_card_Test.ksh) > /dev/null 2>&1
323  status=$?
324
325  if [ ${status} -eq 0 ] ; then
326    echo "Check libIGCM_card ...............................................[ OK ]"
327  else
328    echo "Check libIGCM_card ...........................................[ FAILED ]"
329    echo "--Error--> Execution of ${libIGCM}/libIGCM_card/IGCM_card_Test.ksh"
330    echo "           has produced the file IGCM_card_Test.ref.failed"
331    echo "           Please analyse differences with the reference file by typing:"
332    echo "           diff IGCM_card_Test.ref.failed ${libIGCM}/libIGCM_card/IGCM_card_Test.ref"
333    echo "           Report errors to the author: Patrick.Brockmann@cea.fr"
334    diff ${libIGCM}/libIGCM_card/IGCM_card_Test.ref <(${libIGCM}/libIGCM_card/IGCM_card_Test.ksh)
335    IGCM_debug_Exit "IGCM_card_Check"
336  fi
337}
Note: See TracBrowser for help on using the repository browser.