# -*- coding: iso-8859-1 -*-

# ==============================================================================
# COPYRIGHT (C) 1991 - 2003  EDF R&D                  WWW.CODE-ASTER.ORG
# THIS PROGRAM IS FREE SOFTWARE; YOU CAN REDISTRIBUTE IT AND/OR MODIFY
# IT UNDER THE TERMS OF THE GNU GENERAL PUBLIC LICENSE AS PUBLISHED BY
# THE FREE SOFTWARE FOUNDATION; EITHER VERSION 2 OF THE LICENSE, OR
# (AT YOUR OPTION) ANY LATER VERSION.
#
# THIS PROGRAM IS DISTRIBUTED IN THE HOPE THAT IT WILL BE USEFUL, BUT
# WITHOUT ANY WARRANTY; WITHOUT EVEN THE IMPLIED WARRANTY OF
# MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. SEE THE GNU
# GENERAL PUBLIC LICENSE FOR MORE DETAILS.
#
# YOU SHOULD HAVE RECEIVED A COPY OF THE GNU GENERAL PUBLIC LICENSE
# ALONG WITH THIS PROGRAM; IF NOT, WRITE TO EDF R&D CODE_ASTER,
#    1 AVENUE DU GENERAL DE GAULLE, 92141 CLAMART CEDEX, FRANCE.
# ==============================================================================

"""
Give methods :
- to compile code source, to create catalogue and to build
an executable file,
- to execute Code_Aster...
Methods are called by an ASTER_RUN object.
"""

__revision__ = "$Id: as_exec.py 2646 2006-12-19 13:31:52Z courtois $"


# ----- differ messages translation
def _(mesg):
   return mesg

import os
import sys
import re
import time
import resource
import getpass
from glob           import glob
from types          import FileType

from as_profil      import ASTER_PROFIL
from as_build       import ASTER_BUILD
from as_config      import ASTER_CONFIG
from as_maintenance import get_list, get_version

#-------------------------------------------------------------------------------
def SetParser(run):
   """Configure the command-line parser, add options name to store to the list,
   set actions informations.
   run : ASTER_RUN object which manages the execution
   """
   acts_descr = {
      'run'       : {
         'method' : RunAster,
         'syntax' : '[options] profile',
         'help'   : 'execute the execution described by the profile ' \
               '(default action)'
      },
   }
   run.SetActions(
         actions_descr = acts_descr,
         actions_order = ['run', ],
         group_options = False,
         options_descr = {}
   )

#-------------------------------------------------------------------------------
def RunAster(run, *args):
   """Allow to run Code_Aster with or without compiling additional source files,
   check a development, run a list of test cases...
   """
   run.print_timer = True

   prev = os.getcwd()
   # ----- check argument
   if len(args) != 1:
      run.parser.error(_("'--%s' requires one argument") % run.current_action)

   # 1.
   jn = run['num_job']
   fprof = os.path.join(run['tmp_user'], 'profil_astk.'+jn)
   run.to_delete.append(fprof)

   # 1.1. ----- check argument type
   # 1.1.1. ----- use profile from args
   if isinstance(args[0], ASTER_PROFIL):
      prof = args[0].copy()
   else:
      # 1.1.2. ----- read profile from args
      kret = run.Copy(fprof, args[0], niverr=_('<F>_PROFILE_COPY'))
      prof = ASTER_PROFIL(fprof, run)
   if not prof['mode'][0] in ('batch', 'interactif'):
      run.Mess(_("Unknown mode (%s), use 'interactif' instead") % \
            repr(prof['mode'][0]), _('UNEXPECTED_VALUE'))
      prof['mode'] = ['interactif']

   REPREF  = os.path.join(run.aster_root, prof['version'][0])

   # rep_trav from profile
   reptrav = prof['rep_trav'][0]
   if reptrav == '':
      reptrav = os.path.join(run['rep_trav'], prof['mode'][0]+'.'+jn)
   
   # do not reinitialize rep_trav if 
   if prof['prep_env'][0] != 'no':
      run.Delete(reptrav)
      run.MkDir(reptrav)
   if prof['detr_rep_trav'][0] != 'no':
      run.to_delete.append(reptrav)

   # 1.2. copy profile in rep_trav
   kret = run.Copy(os.path.join(reptrav, jn+'.export'), fprof)

   # 2. ----- initialisations
   dbg = prof['debug'][0]
   if dbg == '':
      dbg = 'nodebug'

   # 2.1. get ASTER_CONFIG and ASTER_BUILD objects
   lconf = prof.Get('D', typ='conf')
   if not lconf:
      ficconf = os.path.join(REPREF, 'config.txt')
   else:
      ficconf = lconf[0]['path']
      if run.IsRemote(ficconf):
         ficconf = os.path.join(reptrav, 'config.txt')
         kret = run.Copy(ficconf, lconf[0]['path'])
      else:
         ficconf = run.PathOnly(ficconf)
   conf = ASTER_CONFIG(ficconf, run)
   build = ASTER_BUILD(run, conf)
   DbgPara = {
      'debug'     : { 'exe'    : conf['BIN_DBG'][0],
                      'suff'   : conf['BINOBJ_DBG'][0],
                      'libast' : conf['BINLIB_DBG'][0],
                      'libfer' : conf['BINLIBF_DBG'][0]},
      'nodebug'   : { 'exe'    : conf['BIN_NODBG'][0],
                      'suff'   : conf['BINOBJ_NODBG'][0],
                      'libast' : conf['BINLIB_NODBG'][0],
                      'libfer' : conf['BINLIBF_NODBG'][0]},
   }

   # 2.1.1. set environment depending on version
   for f in conf.get_with_absolute_path('ENV_SH'):
      run.AddToEnv(f)

   # 2.2. default values
   exetmp  = os.path.join(REPREF, DbgPara[dbg]['exe'])
   cmdetmp = os.path.join(REPREF, conf['BINCMDE'][0])
   eletmp  = os.path.join(REPREF, conf['BINELE'][0])

   # 2.3. profile values
   # it's valid because exec, cmde and ele must appear only once
   # these values will be overidden if they are available in reptrav
   # after an occurence of 'make_...'
   if prof.Get('DR', 'exec'):
      exetmp  = prof.Get('DR', 'exec')[0]['path']
   if prof.Get('DR', 'cmde'):
      cmdetmp = prof.Get('DR', 'cmde')[0]['path']
   if prof.Get('DR', 'ele'):
      eletmp  = prof.Get('DR', 'ele')[0]['path']

   # 2.4. add arguments to find the process (for as_actu/as_del)
   args_supp = ' -num_job '+jn+' -mode '+prof['mode'][0]
   if prof.args.has_key('args'):
      prof.args['args'] += args_supp
   else:
      prof.args['args']  = args_supp

   # order of actions :
   list_actions = ['make_exec',  'make_cmde', 'make_ele',
                   'make_etude', 'make_dbg',  'make_env', 'astout',
                   'exec_crs',   'exec_crp']

   # 3. ==> Let's go !
   # 3.0. check if we know what to do
   for act in prof['actions']:
      if act == '':
         run.Mess(_('nothing to do'), 'OK')
      elif not act in list_actions:
         run.Mess(_('unknown action : %s') % act, _('<A>_ALARM'))

   #
   # 3.1. ----- make_exec
   #
   iret = 0
   if 'make_exec' in prof['actions']:
      exetmp = os.path.join(reptrav, 'aster.exe')
      tit = _('Compilation of source files')
      run.Mess(tit, 'TITLE')
      run.timer.Start(tit)

      repact = os.path.join(reptrav, 'make_exec')
      repobj = os.path.join(repact, 'repobj')
      run.MkDir(repact)
      lf = []
      for typ in ('c', 'f', 'f90'):
         for rep in [l['path'] for l in prof.Get('D', typ=typ)]:
            jret, lbi = build.Compil(typ.upper(), rep, repobj, dbg,
                                     rep_trav=repact, error_if_empty=True)
            iret = max(iret, jret)
            lf.extend(lbi)
      # liste des fichiers surchargés
      vers = get_version(run, REPREF)
      vers = '.'.join(['%2s' % v for v in vers[:3]])
      fsurch = os.path.join(repact, 'surchg.f')
      _listsurcharge(vers, fsurch, lf)
      jret, lbi = build.Compil('F', fsurch, repobj, dbg, repact)
      run.timer.Stop(tit)
      run.CheckOK()

      tit = _('Build executable')
      run.Mess(tit, 'TITLE')
      run.timer.Start(tit)
      libaster = os.path.join(REPREF, DbgPara[dbg]['libast'])
      libferm  = os.path.join(REPREF, DbgPara[dbg]['libfer'])
      # for backward compatibility
      if run.IsDir(libaster):
         libaster = os.path.join(libaster, 'lib_aster.lib')
      if run.IsDir(libferm):
         libferm = os.path.join(libferm, 'ferm.lib')
      lobj = glob(os.path.join(repobj, '*.o'))
      kret = build.Link(exetmp, lobj, libaster, libferm, repact)
      run.timer.Stop(tit)
      run.CheckOK()

      tit = _('Copying results')
      run.timer.Start(tit, num=999)
      for exe in prof.Get('R', typ='exec'):
         run.Delete(exe['path'], remove_dirs=False)
         iret = run.Copy(exe['path'], exetmp)
      run.timer.Stop(tit)
      run.Mess(_('Code_Aster executable successfully created'), 'OK')

   #
   # 3.2. ----- make_cmde
   #
   if 'make_cmde' in prof['actions']:
      cmdetmp = os.path.join(reptrav, conf['BINCMDE'][0])
      run.timer.Start('Compilation of commands catalogue')
      repact = os.path.join(reptrav, 'make_cmde')
      run.MkDir(repact)
      kargs = { 'exe' : exetmp, 'cmde' : cmdetmp, }
      kargs['capy'] = [l['path'] for l in prof.Get('D', typ='capy')]
      if prof.Get('D', typ='py'):
         kargs['py'] = [l['path'] for l in prof.Get('D', typ='py')]
      jret = build.CompilCapy(REPREF, repact, **kargs)      #i18n=True, 
      run.timer.Stop('Compilation of commands catalogue')
      run.CheckOK()

      tit = _('Copying results')
      run.timer.Start(tit)
      for cmde in prof.Get('R', typ='cmde'):
         run.MkDir(cmde['path'])
         iret = run.Copy(cmde['path'], os.path.join(cmdetmp, 'cata*.py*'))
      run.timer.Stop(tit)

   #
   # 3.3. ----- make_ele
   #
   if 'make_ele' in prof['actions']:
      eletmp = os.path.join(reptrav, 'elem.1')
      run.timer.Start('Compilation of elements')
      repact = os.path.join(reptrav, 'make_ele')
      run.MkDir(repact)
      kargs = { 'exe' : exetmp, 'cmde' : cmdetmp, 'ele' : eletmp, }
      kargs['cata'] = [l['path'] for l in prof.Get('D', typ='cata')]
      if prof.Get('D', typ='py'):
         kargs['py'] = [l['path'] for l in prof.Get('D', typ='py')]
      jret = build.CompilEle(REPREF, repact, **kargs)
      run.timer.Stop('Compilation of elements')
      run.CheckOK()

      tit = _('Copying results')
      run.timer.Start(tit)
      for ele in prof.Get('R', typ='ele'):
         iret = run.Copy(ele['path'], eletmp)
      run.timer.Stop(tit)

   #
   # 3.4. ----- make_env / make_etude / make_dbg
   #
   if 'make_env' in prof['actions'] or 'make_etude' in prof['actions'] or \
         'make_dbg' in prof['actions']:
      os.chdir(reptrav)
      run.Mess(_('Code_Aster execution'), 'TITLE')
      
      # 3.4.1. prepare reptrav to run Code_Aster
      kargs = { 'exe'  : exetmp,
                'cmde' : cmdetmp,
                'ele'  : eletmp,
                'lang' : prof['lang'][0], }
      if prof.Get('D', typ='py'):
         kargs['py'] = [l['path'] for l in prof.Get('D', typ='py')]
      run.Mess(_('prepare environment in %s') % reptrav)
      run.timer.Start(_('Preparation of environment'))
      if prof['prep_env'][0] != 'no':
         build.PrepEnv(REPREF, reptrav, dbg=dbg, **kargs)
      else:
         run.Mess(_('... skipped (%s = no) !') % 'prep_env', 'SILENT')
      run.timer.Stop(_('Preparation of environment'))

      # 3.4.2. copy datas (raise <E> errors if failed)
      tit = _('Copying datas')
      run.Mess(tit, 'TITLE')
      run.timer.Start(tit)
      if prof['copy_data'][0] != 'no':
         _copyfiles(run, 'DATA', prof)
      else:
         run.Mess(_('... skipped (%s = no) !') % 'copy_data', 'SILENT')
         print os.getcwd()
      run.timer.Stop(tit)

      diag, tcpu, tsys, ttot, copybase = _execute(
            reptrav,
            multiple       = False,
            with_dbg       = 'make_dbg' in prof['actions'],
            only_env       = 'make_env' in prof['actions'],
            follow_output  = True,
            fpara          = None,
            run=run, conf=conf, prof=prof, build=build, exe=exetmp)

      if not 'make_env' in prof['actions']:
         # 3.4.3. copy results
         tit = _('Copying results')
         run.Mess(tit, 'TITLE')
         run.timer.Start(tit)
         if prof['copy_result'][0] != 'no':
            _copyfiles(run, 'RESU', prof, copybase)
         else:
            run.Mess(_('... skipped (%s = no) !') % 'copy_result', 'SILENT')
         run.timer.Stop(tit)

         run.Mess(_('Code_Aster run ended'), diag)
         # 3.4.4. add .resu/.erre to output for testcases
         if os.path.exists('fort.15'):
            run.Mess(_('Content of RESU file'), 'TITLE')
            _filecat('fort.8', sys.stdout)
            run.Mess(_('Content of ERROR file'), 'TITLE')
            _filecat('fort.9', sys.stdout)
         
         run.CheckOK()
      os.chdir(prev)

   #
   # 3.5. ----- astout
   #
   if 'astout' in prof['actions']:
      os.chdir(reptrav)
      run.Mess(_('Code_Aster tests execution'), 'TITLE')
      
      # 3.6.0. initializations
      ltest = os.path.join(reptrav, 'tests.list')
      if not prof.Get('D', typ='list'):
         run.Mess(_('no list of tests found'), _('<E>_NO_TEST_LIST'))
      else:
         for dli in prof.Get('D', typ='list'):
            if run.IsRemote(dli['path']):
               tmplist = os.path.join(run['tmp_user'], 'list.'+jn)
               run.to_delete.append(tmplist)
               kret = run.Copy(tmplist, dli['path'])
               _filecat(tmplist, ltest)
            else:
               tmplist = run.PathOnly(dli['path'])
               _filecat(tmplist, ltest)
      if not prof.Get('D', typ='rep_test'):
         reptest = []
      else:
         reptest = [r['path'] for r in prof.Get('D', typ='rep_test')]
      if not prof.Get('R', typ='resu_test'):
         run.Mess(_('no result directory found'), ('<E>_NO_RESU_DIR'))
      else:
         resutest = prof.Get('R', typ='resu_test')[0]['path']
         run.MkDir(resutest)

      facmtps = 1.
      nbmaxnook = 5
      cpresok = 'RESNOOK'
      try:
         if prof['facmtps'][0] != '':
            facmtps   = float(prof['facmtps'][0])
      except ValueError:
         run.Mess(_('incorrect value for %s : %s') % ('facmtps', prof['facmtps'][0]))
      try:
         if prof['nbmaxnook'][0] != '':
            nbmaxnook = int(prof['nbmaxnook'][0])
      except ValueError:
         run.Mess(_('incorrect value for %s : %s') % ('nbmaxnook', prof['nbmaxnook'][0]))
      if prof['cpresok'][0] != '':
         cpresok   = prof['cpresok'][0]
      run.CheckOK()
      
      # 3.6.1. prepare reptrav to run Code_Aster
      kargs = { 'exe'  : exetmp,
                'cmde' : cmdetmp,
                'ele'  : eletmp,
                'lang' : prof['lang'][0], }
      if prof.Get('D', typ='py'):
         kargs['py'] = [l['path'] for l in prof.Get('D', typ='py')]
      run.Mess(_('prepare environment in %s') % reptrav)
      run.timer.Start(_('Preparation of environment'))
      build.PrepEnv(REPREF, reptrav, dbg=dbg, **kargs)
      run.timer.Stop(_('Preparation of environment'))

      # get the list of the tests to execute
      iret, list_tests = get_list(ltest)
      if iret != 0:
         run.Mess(_('error during reading file : %s') % ltest, _('<F>_ERROR'))
      nbtest = len(list_tests)
      
      # print a summary
      summary = _("""
--- %d test-cases to run
--- Run started at %s
--- Parameters used for this run :
    Directory of reference files    : %s
    Directory of developper files   : %s
    Directory to copy results       : %s
    Code_Aster version              : %s
    Executable filename             : %s
    Commands catalogue directory    : %s
    Elements catalogue filename     : %s
    Maximum number of errors (NOOK) : %d
    Criteria to copy result files   : %s
    Time multiplicative factor      : %f
""")
      sum_end = _("""
--- All tests finished at %s

--- Results :
""")
      info_start = ( nbtest, time.strftime('%c'),
         os.path.join(REPREF, conf['SRCTEST'][0]), ', '.join(reptest), resutest,
         prof['version'][0], exetmp, cmdetmp, eletmp,
         nbmaxnook, cpresok, facmtps )
      print summary % info_start

      # remove astout profile
      os.remove('%s.export' % jn)

      # 3.6.2. for each test of ltest
      fmt_resu = '%-12s %-18s %8s %8s %8s'
      fmt_tot = '-'*12+' '+'-'*18+' '+'-'*8+' '+'-'*8+' '+'-'*8
      lresu = []
      nbnook = 0
      i = 0
      for test in list_tests:
         i += 1
         run.ReinitDiag('OK')
         tit = _('Running test case : %s (%d/%d)...') % (test, i, nbtest)
         run.Mess(tit, 'TITLE')
         
         # copy datas
         ptest = prof.copy()
         ptest.data = []
         ptest.resu = []
         ptest.filename = '%s.export' % test
         _copytestD(run, conf, test, REPREF, reptest, reptrav, ptest)
         fpara = os.path.join(reptrav, '%s.para' % test)
         
         # write export file in current directory
         iret, dico = _getpara(run, fpara, conf['plate-forme'][0])
         if iret == 0:
            ptest.args['memjeveux'] = dico['memjeveux']
            ptest.args['tpmax'] = dico['tps_job']
            ptest['mem_aster'] = dico['mem_aster']
         ptest['actions'] = 'make_etude'
         ptest.WriteExportTo(ptest.filename)
         
         # execute the test
         diag, tcpu, tsys, ttot, validbase = _execute(
            reptrav,
            multiple       = True,
            with_dbg       = False,
            only_env       = False,
            follow_output  = False or run['verbose'],
            fpara          = fpara,
            facmtps        = facmtps,
            cas_test       = True,
            run=run, conf=conf, prof=prof, build=build, exe=exetmp)
         lresu.append([test, diag, tcpu, tsys, ttot])
         print fmt_resu % tuple(lresu[-1])

         # 3.6.2.9. copy results
         tit = _('Copying results')
         run.timer.Start(tit)
         if cpresok == 'RESOK' or \
           (cpresok == 'RESNOOK' and run.GetGrav(diag) > run.GetGrav('<A>')):
            _copytestR(run, test, reptrav, resutest)
         run.timer.Stop(tit)

         # count nook
         if run.GetGrav(diag) >= run.GetGrav('NOOK'):
            nbnook += 1
         if nbnook >= nbmaxnook:
            run.Mess(_('Maximum number of errors reached : %d') % nbmaxnook,
                  _('<E>_ERROR'))
            break

         # clear reptrav for next execution
         # delete all but not exetmp, eletmp, REPPY + ltest
         lf = glob('*')
         for k in (os.path.basename(exetmp), 'elem.1', conf['REPPY'][0],
                   os.path.basename(ltest),
                   'REPE_OUT', 'RESU_ENSIGHT'):
            try:
               lf.remove(k)
            except ValueError:
               pass
         for f in lf:
            run.Delete(f)

      # Summary
      tit = _('Summary of the run')
      run.Mess(tit, 'TITLE')
      print summary % info_start
      print sum_end % time.strftime('%c')
      t = [0., 0., 0.]
      lresu.sort()
      for lin in lresu:
         t[0] += float(lin[2])
         t[1] += float(lin[3])
         t[2] += float(lin[4])
         print fmt_resu % tuple(lin)
      print fmt_tot
      print fmt_resu % (_('%d tests') % i, _('%d errors') % nbnook,
            t[0], t[1], t[2])
      # force global diagnostic to <F>_ERROR if errors occured
      if nbnook > 0:
         run.diag = _('<E>_ERROR')
      run.CheckOK()
      os.chdir(prev)

   # 3.7. ----- exec_crs
   #
   if 'exec_crs' in prof['actions']:
      repsrc = os.path.join(reptrav, 'sources')
      reptmp = os.path.join(reptrav, 'tmp')
      fmsg = os.path.join(reptrav, 'messages')
      run.MkDir(repsrc)

      tit = _('Copy of source files')
      run.Mess(tit, 'TITLE')
      run.timer.Start(tit)
      lf  = prof.Get('D', typ='f')
      for rep in [l['path'] for l in lf]:
         if run.IsDir(rep):
            src = os.path.join(rep, '*.f')
         else:
            src = rep
         iret = run.Copy(repsrc, src)
      run.timer.Stop(tit)

      # command line
      tit = _('Execution of CRS')
      run.Mess(tit+_(' (Syntax Rules Control)'), 'TITLE')
      cmd = []
      cmd.extend(conf['CRS'])
      cmd.append(repsrc)
      cmd.append(fmsg)
      cmd.append(reptmp)

      run.timer.Start(tit)
      iret, output = run.Shell(' '.join(cmd), follow_output=True)
      if os.path.exists(fmsg):
         run.Mess(_('content of messages files :'))
         f = open(fmsg, 'r')
         print f.read()
         f.close()
      else:
         run.Mess(_('messages file not found !'), _('<A>_ALARM'))
      
      if iret == 0:
         diag = 'OK'
      else:
         diag = '<E>_AGLA'
      run.Mess(tit, diag)
      run.timer.Stop(tit)

   if 'exec_crp' in prof['actions']:
      repsrc = os.path.join(reptrav, 'sources')
      reptmp = os.path.join(reptrav, 'tmp')
      fmsg = os.path.join(reptrav, 'messages')
      run.MkDir(repsrc)

      tit = _('Copy of source files')
      run.Mess(tit, 'TITLE')
      run.timer.Start(tit)
      lf  = prof.Get('D', typ='f')
      for rep in [l['path'] for l in lf]:
         if run.IsDir(rep):
            src = os.path.join(rep, '*.f')
         else:
            src = rep
         iret = run.Copy(repsrc, src)
      lfun = prof.Get('D', typ='unig')
      if lfun:
         funig = lfun[0]
      else:
         funig = 'bidon'
      run.timer.Stop(tit)

      # command line
      tit = _('Execution of CRP')
      run.Mess(tit+_(' (Programmation Rules Control)'), 'TITLE')
      cmd = []
      cmd.extend(conf['CRP'])
      cmd.append(repsrc)
      cmd.append(funig)
      cmd.append(fmsg)
      cmd.append(reptmp)

      run.timer.Start(tit)
      iret, output = run.Shell(' '.join(cmd), follow_output=True)
      if os.path.exists(fmsg):
         run.Mess(_('content of messages files :'))
         f = open(fmsg, 'r')
         print f.read()
         f.close()
      else:
         run.Mess(_('messages file not found !'), _('<A>_ALARM'))
      
      if iret == 0:
         diag = 'OK'
      else:
         diag = _('<E>_CRP_ERROR')
      run.Mess(tit, diag)
      run.timer.Stop(tit)

   # 4. ----- clean up
   if 'make_env' in prof['actions'] and prof['detr_rep_trav'][0] != 'no':
      run.to_delete.remove(reptrav)

#-------------------------------------------------------------------------------
def _execute(reptrav, multiple=False, with_dbg=False, only_env=False,
         follow_output=True, fpara=None, facmtps=1., **kargs):
   """Run a Code_Aster execution in 'reptrav'.
   Arguments :
      cmd      : command line to complete,
      multiple : False if only one execution is run (so stop if it fails),
         True if several executions are run (don't stop when error occurs)
      with_dbg : start debugger or not,
      fpara    : .para file, if None memory, time limits and number of cpu are
         read in prof,
      follow_output : print output to follow the execution,
   kargs give "run, conf, prof, build" instances + exec name
   Return a tuple (diag, tcpu, tsys, ttot, validbase).
   """
   # 1. ----- initializations
   run    = kargs['run']
   conf   = kargs['conf']
   prof   = kargs['prof']
   build  = kargs['build']
   exetmp = kargs['exe']
   ctest  = kargs.get('cas_test', False)
   tcpu = 0.
   tsys = 0.
   ttot = 0.
   validbase = True
   
   interact = prof.args.has_key('interact') or \
              prof.args['args'].find('-interact') > -1

   os.chdir(reptrav)

   # 2. ----- list of command files
   list_comm = glob('fort.1.*')
   list_comm.sort()
   if os.path.exists('fort.1'):
      list_comm.insert(0, 'fort.1')

   # 3. ----- arguments list
   cmd = []
   cmd.append(os.path.join(conf['REPPY'][0], conf['ARGPYT'][0]))
   cmd.extend(conf['ARGEXE'])
   cmd.append('-commandes fort.1 -rep none')
   for k, v in prof.args.items():
      if k == 'args':
         cmd.append(prof.args[k])
      elif not (fpara and k in ('memjeveux', 'tpmax')):
         cmd.append('-%s %s' % (k, v))
   # arguments which can be set in file 'config.txt'
   for kconf, karg in { 'REPOUT' : 'rep_outils', 'REPMAT' : 'rep_mat',
                        'REPDEX' : 'rep_dex'}.items():
      if conf[kconf][0] != '' and not karg in prof.args.keys():
         cmd.append('-'+karg+' '+conf[kconf][0])

   ncpus = '1'
   if prof['ncpus'][0] != '':
      ncpus = prof['ncpus'][0]

   # 4. ----- add parameters from prof or fpara if present
   if re.search('64$', conf['plate-forme'][0]):
      facW = 8
   else:
      facW = 4
   tps  = 0
   memj = 0
   nbp  = 0
   if fpara:
      kret, dpara = _getpara(run, fpara, conf['plate-forme'][0])
      if kret != 0:
         run.Mess(_('can not parse parameter file : %s') % fpara, _('<E>_ERROR'))
         return run.diag, str(tcpu), str(tsys), str(ttot), validbase
      memj = dpara['memjeveux']
      cmd.append('-memjeveux '+str(memj))
      tps = int(dpara['tps_job']*facmtps)
      cmd.append('-tpmax '+str(tps))
      if dpara['ncpus'] != 0:
         ncpus = dpara['ncpus']
   else:
      try:
         tps = int(prof.args['tpmax'])
      except KeyError:
         run.Mess(_('tpmax not provided in profile'), _('<E>_INCORRECT_PARA'))
      except ValueError:
         run.Mess(_('incorrect value for tpmax (%s) in profile') % \
               prof.args['tpmax'], _('<E>_INCORRECT_PARA'))
      try:
         memj = float(prof.args['memjeveux'])
      except KeyError:
         run.Mess(_('memjeveux not provided in profile'), _('<E>_INCORRECT_PARA'))
      except ValueError:
         run.Mess(_('incorrect value for memjeveux (%s) in profile') % \
               prof.args['memjeveux'], _('<E>_INCORRECT_PARA'))
   try:
      nbp = int(ncpus)
   except ValueError:
      run.Mess(_('incorrect value for ncpus (%s) in profile') % \
            prof['ncpus'][0], _('<E>_INCORRECT_PARA'))
   nf = '%s.para' % run['num_job']
   if ctest:
      nf = 'test.para'
   _fillpara(run, filename=nf, tps_job=tps, memjMo=memj*facW,
             mem_aster=prof['mem_aster'], ncpus=nbp)

   # 4.1. check for memory, time and procs limits
   run.Mess(_('Parameters : memory %d MB - time limit %d s') % (memj*facW, tps))
   _check_limits(run, prof['mode'][0], tps, memj*facW, nbp)
   run.CheckOK()

   # 5. ----- only environment, print command lines to execute
   if only_env:
      run.Mess(_('Code_Aster environment prepared in %s') % reptrav, 'OK')
      run.Mess(_('To start execution copy/paste following lines in a ksh/bash shell :'))
      run.Mess('   cd %s' % reptrav, 'SILENT')
      run.Mess('   export ASTER_VERSION=%s' % prof['version'][0], 'SILENT')
      run.Mess('   . %s' % os.path.join(run.confdir, 'aster_profile.sh'), 'SILENT')
      # set per version environment
      for f in conf.get_with_absolute_path('ENV_SH'):
         run.Mess('   . %s' % f, 'SILENT')
      
      cmd.insert(0, os.path.join('.', os.path.basename(exetmp)))
      cmdline = ' '.join(cmd)
      
      # get pdb.py path
      pdbpy_cmd = "import os, sys ; " \
         "pdbpy = os.path.join(sys.prefix, 'lib', 'python' + sys.version[:3], 'pdb.py')"
      d = {}
      exec pdbpy_cmd in d
      pdbpy = d['pdbpy']
      
      # print command lines
      k = 0
      for fcomm in list_comm:
         k += 1
         cmd_2 = cmdline.replace('fort.1', fcomm)
         run.Mess(_('Command line %d :') % k)
         run.Mess(cmd_2, 'SILENT')
         # how to start the Python debugger
         run.Mess(_('To start execution in the Python debugger you could type :'), 'SILENT')
         pdb_cmd = cmd_2.replace(os.path.join('.', os.path.basename(exetmp)),
            '%s %s' % (os.path.join('.', os.path.basename(exetmp)),
                     ' '.join(pdbpy.splitlines())))
         run.Mess(pdb_cmd, 'SILENT')

      diag = 'OK'

   # 6. ----- really execute
   else:
      # 6.1. content of reptrav
      if follow_output:
         run.Mess(_('Content of %s before execution') % reptrav, 'TITLE')
         kret, out = run.Shell(cmd='ls -la', follow_output=follow_output)

      if len(list_comm) == 0:
         run.Mess(_('no .comm file found'), _('<E>_NO_COMM_FILE'))
      # check for previous errors (copy datas)
      if not multiple:
         run.CheckOK()
      elif run.GetGrav(run.diag) > run.GetGrav('<A>'):
         run.Mess(_('error occurs during preparing data : %s') % run.diag)
         return run.diag, str(tcpu), str(tsys), str(ttot), validbase

      # 6.2. complete command line
      cmd.append('-suivi_batch')
      if with_dbg:
         # how to run the debugger
         cmd_dbg = run.config.get('cmd_dbg', '')
         if not cmd_dbg:
            run.Mess(_('command line to run the debugger not defined'),
                  _('<F>_DEBUG_ERROR'))
         if cmd_dbg.find('gdb') > -1:
            ldbg = ['break main', ]
         else:
            ldbg = ['stop in main', ]
         ldbg.append('run '+' '.join(cmd))
         cmd = _getdbgcmd(cmd_dbg, os.path.basename(exetmp), '', ldbg)
      else:
         cmd.insert(0, os.path.join('.', os.path.basename(exetmp)))
         cmd.append('| tee fort.6')
         os.environ['OMP_NUM_THREADS'] = ncpus
         # unlimit coredump size
         try:
            corefilesize = int(prof['corefilesize'][0]) * 1024*1024
         except ValueError:
            corefilesize = 'unlimited'
         run.SetLimit('core', corefilesize)

      # 6.3. info if multiple .comm files
      if len(list_comm)>1:
         run.Mess(_('%d command files') % len(list_comm))
         validbase = False
         BASE_PREC = os.path.join(reptrav, 'BASE_PREC')
         run.MkDir(BASE_PREC)

      # 6.4. for each .comm file
      diag = '?'
      k = 0
      for fcomm in list_comm:
         k += 1
         os.rename(fcomm, 'fort.1')

         # start execution
         tit = _('Code_Aster run')
         run.timer.Start(tit)
         if follow_output:
            run.Mess(tit, 'TITLE')
            run.Mess(_('Command line %d :') % k)
            if not run['verbose']:
               run.Mess(' '.join(cmd))
         iret, output = run.Shell(' '.join(cmd), follow_output=follow_output,
               interact=interact)
#          f6 = open('fort.6', 'a')
#          f6.write(output)
#          f6.close()
         run.timer.Stop(tit)
         if k < len(list_comm):
            for b in glob('vola.*')+glob('loca.*'):
               run.Delete(b)

         if len(list_comm) > 1:
            ldiag = build.GetDiag(cas_test=ctest)
            diag_k  = ldiag[0]
            tcpu += float(ldiag[1])
            tsys += float(ldiag[2])
            ttot += float(ldiag[3])
            _filecat('fort.6', 'fort_bis.6')
            _filecat('fort.8', 'fort_bis.8')
            _filecat('fort.9', 'fort_bis.9')
            run.Delete('fort.6')
            run.Delete('fort.8')
            run.Delete('fort.9')
            if re.search('<[ESF]{1}>', diag_k):
               # switch <F> to <E> if multiple .comm
               if diag_k.find('<F>') > -1:
                  diag_k = diag_k.replace('<F>', '<E>')
                  # ...and try to restore previous bases
                  if follow_output:
                     run.Mess(_('restore bases from %s') % BASE_PREC)
                  lbas = glob(os.path.join(BASE_PREC, 'glob.*')) + \
                         glob(os.path.join(BASE_PREC, 'bhdf.*')) + \
                         glob(os.path.join(BASE_PREC, 'pick.*'))
                  if len(lbas) > 0:
                     run.Copy(reptrav, niverr='INFO', verbose=follow_output, *lbas)
                  else:
                     run.Mess(_('no glob/bhdf base to restore'), _('<A>_ALARM'))
               run.Mess(_('execution aborted (comm file #%d)') % k, diag_k)
               diag = diag_k
               break
            else:
               # save bases in BASE_PREC if next execution fails
               validbase = True
               if k < len(list_comm):
                  if follow_output:
                     run.Mess(_('save bases into %s') % BASE_PREC)
                  lbas = glob(os.path.join(reptrav, 'glob.*')) + \
                         glob(os.path.join(reptrav, 'bhdf.*')) + \
                         glob(os.path.join(reptrav, 'pick.*'))
                  run.Copy(BASE_PREC, niverr='INFO', verbose=follow_output, *lbas)
               run.Mess(_('execution ended (comm file #%d)') % k, diag_k)
            # the worst diagnostic
            if run.GetGrav(diag) < run.GetGrav(diag_k):
               diag = diag_k

      # 6.5. global diagnostic
      if len(list_comm) > 1:
         os.rename('fort_bis.6', 'fort.6')
         os.rename('fort_bis.8', 'fort.8')
         os.rename('fort_bis.9', 'fort.9')
      else:
         diag, tcpu, tsys, ttot = build.GetDiag(cas_test=ctest)
         validbase = run.GetGrav(diag) <= run.GetGrav('<S>')
      if ctest and run.GetGrav(diag) < 0:
         diag = '<F>_' + diag
      run.Mess(_('Code_Aster run ended, diagnostic : %s') % diag)

      # 6.6. post-mortem analysis of the core file
      if not with_dbg:
         cmd_dbg = run.config.get('cmd_post', '')
         lcor = glob('core*')
         if cmd_dbg and lcor:
            run.Mess(_('Code_Aster run created a coredump'),
                  _('<E>_CORE_FILE'))
            if not multiple:
               # take the first one if several core files
               core = lcor[0]
               run.Mess(_('core file name : %s') % core)
               cmd = _getdbgcmd(cmd_dbg, os.path.basename(exetmp), core,
                     ('where', 'quit'))
               tit = _('Coredump analysis')
               run.Mess(tit, 'TITLE')
               run.timer.Start(tit)
               iret, output = run.Shell(' '.join(cmd),
                     alt_comment='coredump analysis...', verbose=True)
               if iret == 0:
                  print output
               run.timer.Stop(tit)

      # 6.7. content of reptrav
      if follow_output:
         run.Mess(_('Content of %s after execution') % reptrav, 'TITLE')
         kret, out = run.Shell(cmd='ls -la . REPE_OUT', follow_output=follow_output)

      # 6.8. print some informations
      if follow_output:
         run.Mess(_('Size of bases'), 'TITLE')
         lf = glob('vola.*')
         lf.extend(glob('loca.*'))
         lf.extend(glob('glob.*'))
         lf.extend(glob('bhdf.*'))
         lf.extend(glob('pick.*'))
         for f in lf:
            run.Mess(_('size of %s : %12d bytes') % (f, os.stat(f).st_size))

   return diag, str(tcpu), str(tsys), str(ttot), validbase


#-------------------------------------------------------------------------------
def _copyfiles(run, mode, prof, copybase=True):
   """Copy datas from profile into `pwd` (if mode=='DATA')
   or results from `pwd` into destination given by profile (if mode=='RESU').
   Aster bases are copied only if copybase is True.
   Raise only <E> if an error occurs run CheckOK() after.
   """
   if mode == 'DATA':
      l_dico = prof.data
      icomm = 0
      for df in l_dico:
         icomm = _copyfileD(run, df, icomm)
   else:
      l_dico = prof.resu
      for df in l_dico:
         _copyfileR(run, df, copybase)

#-------------------------------------------------------------------------------
def _copyfileD(run, df, icomm):
   """Copy datas from `df` into current directory.
   Raise only <E> if an error occurs run CheckOK() after.
   """
   dest = None
   # 1. ----- if logical unit is set : fort.*
   if df['ul'] != '0':
      dest = 'fort.' + df['ul']
      # exception for multiple command files (adding _N)
      if df['ul'] == '1':
         icomm += 1
         dest = dest + '.%d' % icomm
      # warning if file already exists
      if run.Exists(dest):
         run.Mess(_("'%s' overwrites '%s'") % (df['path'], dest), _('<A>_COPY_DATA'))
      if df['compr']:
         dest = dest + '.gz'

   # 2. ----- bases and directories (ul=0)
   else:
      # base
      if df['type'] in ('base', 'bhdf'):
         dest = os.path.basename(df['path'])
      # ensi
      elif df['type'] == 'ensi':
         dest = 'DONNEES_ENSIGHT'
      # repe
      elif df['type'] == 'repe':
         dest = 'REPE_IN'
      
   if dest is not None:
      # 3. --- copy
      kret = run.Copy(dest, df['path'], niverr=_('<E>_COPY_ERROR'), verbose=True)

      # 4. --- decompression
      if kret == 0 and df['compr']:
         kret, f = run.Gunzip(dest, niverr=_('<E>_DECOMPRESSION'), verbose=True)

      # 5. --- move the bases in main directory
      if df['type'] in ('base', 'bhdf'):
         for f in glob(os.path.join(dest, '*')):
            os.rename(f, os.path.basename(f))
   
   return icomm

#-------------------------------------------------------------------------------
def _copyfileR(run, df, copybase=True):
   """Copy results from current directory into destination given by `df`.
   Aster bases are copied only if copybase is True.
   Raise only <E> if an error occurs run CheckOK() after.
   """
   # list of files
   lf = []
   isdir = False
   
   # 1. ----- files
   if df['ul'] != '0' or df['type'] in ('nom','para'):
      # if logical unit is set : fort.*
      if df['ul'] != '0':
         lf.append('fort.' + df['ul'])
      elif df['type'] == 'para':
         fpara = '%s.para' % run['num_job']
         lf.append(fpara)
      elif df['type'] == 'nom':
         lf.append(os.path.basename(df['path']))

   # 2. ----- bases and directories (ul=0)
   else:
      isdir = True
      # base
      if df['type'] == 'base' and copybase:
         lf.extend(glob('glob.*'))
         lf.extend(glob('pick.*'))
      # bhdf
      elif df['type'] == 'bhdf' and copybase:
         lbas = glob('bhdf.*')
         if len(lbas) == 0:
            run.Mess(_("No 'bhdf' found, saving 'glob' instead"), _('<A>_COPY_BASE'))
            lbas = glob('glob.*')
         lf.extend(lbas)
         lf.extend(glob('pick.*'))
      # ensi
      elif df['type'] == 'ensi':
         lf.extend(glob(os.path.join('RESU_ENSIGHT', '*')))
      # repe
      elif df['type'] == 'repe':
         lf.extend(glob(os.path.join('REPE_OUT', '*')))
      
   # 3. ----- compression
   kret = 0
   if df['compr']:
      lfnam = lf[:]
      lf = []
      for fnam in lfnam:
         kret, f = run.Gzip(fnam, niverr=_('<E>_COMPRES_ERROR'),
               verbose=True)
         lf.append(f)
   
   # 4. ----- copy
   if kret == 0 and len(lf) > 0:
      # create destination
      if isdir:
         kret = run.MkDir(df['path'], _('<E>_MKDIR_ERROR'))
      elif len(lf) > 1:
         run.Mess(_("""Only the first of [%s] one is copied.""" % ', '.join(lf)),
               _('<A>_COPYFILE'))
         lf = [lf[0],]
      # copy
      if kret == 0:
         kret = run.Copy(df['path'], niverr=_('<E>_COPY_ERROR'),
               verbose=True, *lf)
      # save base if failure
      if kret != 0 and df['type'] in ('base', 'bhdf'):
         tmp = '%s_base_%s' % (getpass.getuser(), run['num_job'])
         rescue = os.path.join(run['rep_trav'], tmp)
         run.Mess(_("Saving results in a temporary directory (%s).") % rescue,
               _('<A>_COPY_BASE'), store=True)
         kret = run.MkDir(rescue)
         kret = run.Copy(rescue, niverr=_('<E>_COPY_ERROR'),
               verbose=True, *lf)


#-------------------------------------------------------------------------------
def _copytestD(run, conf, test, REPREF, reptest, reptrav, ptest):
   """Copy needed files to run 'test' in 'reptrav' : First take files from
   'REPREF' and eventually complete with files from 'reptest'.
   Fill the ASTER_PROFIL `ptest`.
   """
   # supported file types + ['com?', '[0-9]*']
   dtyp = {
      'comm' : ('fort.1' ,  1), 
      'mail' : ('fort.20', 20),
      'datg' : ('fort.16', 16),
      'mgib' : ('fort.19', 19),
      'msh'  : ('fort.19', 19),
      'msup' : ('fort.19', 19),
      'para' : ('%s.para' % test, 0),
      'ensi' : ('DONNEES_ENSIGHT', 0),
      'repe' : ('REPE_IN', 0)
   }
   REPTEST = os.path.join(REPREF, conf['SRCTEST'][0])
   if run.IsRemote(REPTEST):
      run.Mess(_('REPREF (%s) should be on exec host') % REPTEST,
            _('<F>_INVALID_DIR'))
   else:
      REPTEST = run.PathOnly(REPTEST)
   for v in dtyp.values():
      run.Delete(v[0])

   # copy files from REPTEST and 'reptest' if not empty
   lrep = [REPTEST]
   if reptest:
      lrep.extend(reptest)
   for src in lrep:
      for typ in dtyp.keys() + ['com?', '[0-9]*']:
         f = os.path.join(src, '%s.%s' % (test, typ))
         if not typ in dtyp.keys() or run.Exists(f):
            run.Copy(reptrav, f, niverr='SILENT')

   lf = glob(os.path.join(reptrav, test)+'.*')
   icomm = 0
   for f in lf:
      suff = f.split('.')[-1]
      typ = suff
      dico = {}
      if suff in dtyp.keys() or suff.isdigit():
         dest = 'fort.' + suff
         if suff in dtyp.keys():
            dest, suff = dtyp[suff]
         else:
            typ = 'libr'
         if run.Exists(dest) and os.path.basename(f) != dest:
            run.Mess(_("'%s' overwrites '%s'") % (os.path.basename(f), dest),
                     _('<A>_COPY_DATA'))
         dico = {
            'type'  : typ,
            'path'  : os.path.join(reptrav, dest),
            'isrep' : typ in ('ensi', 'repe'),
            'ul'    : suff,
            'compr' : False,
         }
         os.rename(f, os.path.join(reptrav, dest))
      else:
         mat = re.search('com([0-9]+)', suff)
         if mat:
            icomm += 1
            fdest = os.path.join(reptrav, 'fort.1.%d' % icomm)
            os.rename(f, fdest)
            dico = {
               'type'  : 'comm',
               'path'  : f,
               'isrep' : False,
               'ul'    : 1,
               'compr' : False,
            }
      if dico:
         ptest.Set('D', dico)

#-------------------------------------------------------------------------------
def _copytestR(run, test, reptrav, resutest):
   """Copy standard results of a test from 'reptrav' to 'resutest'.
   """
   # supported file types
   dtyp = {'fort.6' : 'mess', 'fort.8' : 'resu', 'fort.9' : 'erre' }
   for f in dtyp.keys():
      fic = os.path.join(reptrav, f)
      if os.path.exists(fic):
         run.Copy(os.path.join(resutest, test+'.'+dtyp[f]), fic,
               niverr=_('<A>_COPY_TEST'))

#-------------------------------------------------------------------------------
def _getdbgcmd(cmd_dbg, exe, core, lcmd):
   """Return the command line (as list) to run 'lcmd' in the debugger.
      @E : executable
      @C : coredump filename
      @D : filename of debugger commands
      @d : string of debugger commands
   """
   # debugger commands string
   cstr = ' ; '.join(lcmd)
   ftmp = 'dbg_cmdfile'
   # fill debugger commands file
   f = open(ftmp, 'w')
   f.write(os.linesep.join(lcmd) + os.linesep)
   f.close()
   # replace @ codes
   cmd = cmd_dbg.replace('@E', exe)
   cmd = cmd.replace('@C', core)
   cmd = cmd.replace('@D', ftmp)
   cmd = cmd.replace('@d', cstr)
   return [cmd]

#-------------------------------------------------------------------------------
def _listsurcharge_u2mess(fsurch, lf):
   """Write the fortran subroutine "surchg.f".
      fsurch : subroutine filename
      lf     : list of modified files
   """
   header = """
      SUBROUTINE SURCHG(IFM)
C --- IFM CONSERVE POUR LA COMPATIBILITE
      INTEGER IFM
      INTEGER NBFILE
      CHARACTER*16  VALK(%(nbfile)s)"""
      #CALL UTMESS('A', 'SURCHG', 'VERSION SURCHARGEE PAR :')
   fmt_line = "      VALK(%(indice)d) = '%(subroutine)s%(separ)s'"
   fmt_call = "      CALL U2MESK('A','SUPERVIS_40',%(nbfile)s,VALK)"
   footer = "      END"
   cont = []
   l_file = [os.path.basename(f) for f in lf]
   l_file.sort()
   nbfile = len(l_file)
   cont.append(header % { 'nbfile' : nbfile })
   npl = 6
   for i, file in enumerate(l_file):
      sep = ', '
      if i + 1 == len(l_file):
         sep = ''
      cont.append(fmt_line % { 'indice' : i + 1, 'subroutine' : file, 'separ' : sep })
   
   cont.append(fmt_call % { 'nbfile' : nbfile })
   cont.append(footer)
   
   open(fsurch, 'w').write(os.linesep.join(cont))
   #print os.linesep.join(cont)

#-------------------------------------------------------------------------------
def _listsurcharge_utmess(fsurch, lf):
   """Write the fortran subroutine "surchg.f".
      fsurch : subroutine filename
      lf     : list of modified files
   """
   cont = ["""      SUBROUTINE SURCHG(IFM)
      INTEGER IFM
      CALL UTMESS('A', 'SURCHG', 'VERSION SURCHARGEE PAR :')"""]
   templ = "      WRITE(IFM,'(3X,A)') '"
   sep = ', '
   lmax = 72
   len0 = len(templ)
   files = [os.path.basename(f) for f in lf]
   files.sort()
   while len(files)>0:
      lig = []
      clen = len0-len(sep)
      while len(files)>0 and clen+len(files[0])+len(sep) <= lmax-1:
         clen = clen+len(files[0])+len(sep)
         lig.append("%s" % files.pop(0))
      cont.append(templ + sep.join(lig) + "'")
      # si on n'a rien pu ajouter, il faut tronquer
      if clen == len0-len(sep):
         files[0] = files[0][:lmax-1-clen-len(sep)]
   cont.extend(['      END', ''])
   f = open(fsurch, 'w')
   f.write(os.linesep.join(cont))
   f.close()

#-------------------------------------------------------------------------------
def _listsurcharge(version, fsurch, lf):
   """Aiguillage pour les versions avant U2MESS ( < 8.3.14)
   """
   if version < ' 8. 3.14':
      func = _listsurcharge_utmess
   else:
      func = _listsurcharge_u2mess
   func(fsurch, lf)


#-------------------------------------------------------------------------------
def _getpara(run, fpara, platform=None):
   """Return a dict object by parsing the file 'fpara' written as :
   param_name1 value1 param_name2 value2...
   (parameters name should be in list_param).
   Be careful : tps_job is in seconds in fpara and in minutes in .export (LSF) !
   """
   list_param = ['mem_job', 'tps_job', 'ncpus', 'mem_aster']
   iret = 0
   dico = {}
   for k in list_param:
      dico[k] = 0

   # ----- check that file exists
   if not os.path.exists(fpara):
      iret = 1
      run.Mess(_('file not found : %s') % fpara, _('<E>_FILE_NOT_FOUND'))
      return iret, {}

   # ----- parsing
   f = open(fpara, 'r')
   for str0 in f:
      line = str0.split()
      while len(line)>0:
         w = line.pop(0)
         if w in list_param:
            dico[w] = line.pop(0)
   f.close()

   # ----- ncpus keep as string...
   # ----- convert time to int
   try:
      dico['tps_job'] = int(dico['tps_job'])
   except ValueError:
      run.Mess(_('incorrect value for tps_job (%s) in %s') % \
            (dico['tps_job'], fpara), _('<E>_INCORRECT_PARA'))

   # ----- delete 'Mo' in mem_job value
   try:
      dico['mem_job'] = int(dico['mem_job'].replace('Mo', ''))
   except ValueError:
      run.Mess(_('incorrect value for mem_job (%s) in %s') % \
            (dico['mem_job'], fpara), _('<E>_INCORRECT_PARA'))

   # ----- convert mem_aster to int
   try:
      dico['mem_aster'] = int(dico['mem_aster'])
   except ValueError:
      run.Mess(_('incorrect value for mem_aster (%s) in %s') % \
            (dico['mem_aster'], fpara), _('<E>_INCORRECT_PARA'))
   if dico['mem_aster'] == 0:
      dico['mem_aster'] = 100
   
   if platform is not None:
      if re.search('64$', platform):
         facW = 8
      else:
         facW = 4
      dico['memjeveux'] = dico['mem_job'] / facW * dico['mem_aster'] / 100.
   
   return iret, dico

#-------------------------------------------------------------------------------
def _fillpara(run, **kargs):
   """Write a file `pid`.para in current directory similar to testcases ones.
   """
   form = 'tps_job %(tps_job)d mem_job %(mem_job)dMo '\
          'mem_aster %(mem_aster)d ncpus %(ncpus)d\n'
   dform = kargs.copy()
   
   try:
      dform['tps_job']   = int(kargs['tps_job'])
      dform['mem_aster'] = int(kargs['mem_aster'][0] or '100')
      dform['mem_job']   = int(kargs['memjMo'] * 100. / dform['mem_aster'])
      dform['ncpus']     = int(kargs['ncpus'])
      open(kargs['filename'], 'w').write(form % dform)
   except Exception, msg:
      run.DBG(kargs)

#-------------------------------------------------------------------------------
def _check_limits(run, mode, tps, mem, nbp):
   """Return True if 'tps', 'mem' and 'nbp' are less than limits defined in
   configuration file, False else.
   """
   # time
   err = False
   tpsmax = 0
   stps = run[mode+'_tpsmax'].split(':')
   try:
      m = 1
      while len(stps)>0:
         tpsmax += int(stps.pop())*m
         m = m*60
   except ValueError:
      err = True
   if len(stps)>3:
      err = True
   if err:
      run.Mess(_('Incorrect value (%s) for %s') % \
            (str(run[mode+'_tpsmax']), mode+'_tpsmax'), _('<F>_CONFIG_ERROR'))
   if tps > tpsmax:
      run.Mess(_("""Requested time (%s s) is higher than the limit (%s s)""") % \
            (tps, tpsmax), _('<E>_INCORRECT_PARA'))
   # memory
   try:
      memmax = int(run[mode+'_memmax'])
   except ValueError:
      run.Mess(_('Incorrect value (%s) for %s') % \
            (str(run[mode+'_memmax']), mode+'_memmax'), _('<F>_CONFIG_ERROR'))
   if mem > memmax:
      run.Mess(_("""Requested memory (%s MB) is higher than the limit (%s MB)""")%\
            (mem, memmax), _('<E>_INCORRECT_PARA'))
   # ncpus
   try:
      nbpmax = int(run[mode+'_nbpmax'])
   except ValueError:
      run.Mess(_('Incorrect value (%s) for %s') % \
            (str(run[mode+'_nbpmax']), mode+'_nbpmax'), _('<F>_CONFIG_ERROR'))
   if nbp > nbpmax:
      run.Mess(_("""Requested number of processors (%s) is higher than the limit (%s)""") %\
            (nbp, nbpmax), _('<E>_INCORRECT_PARA'))

#-------------------------------------------------------------------------------
def _filecat(src, dest):
   """Append content of 'src' to 'dest' (filename or file object).
   """
   if not type(dest) is FileType:
      f2 = open(dest, 'a')
   else:
      f2 = dest
   
   if os.path.exists(src):
      f1 = open(src, 'r')
      f2.write(f1.read())
      f1.close()
   
   if not type(dest) is FileType:
      f2.close()

