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

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