subroutine sic_load(lang,help,scom,ccom,version)
  use sic_dependencies_interfaces
  use sic_interfaces, except_this=>sic_load
  use sic_dictionaries
  use sic_interactions
  use gbl_message
  use gildas_def
  !---------------------------------------------------------------------
  ! @ public (but private in the context of new language initialization)
  !       Initialise a SIC vocabulary
  ! Arguments :
  !       LANG    C*(*)   Language name
  !       HELP    C*(*)   Logical name for help file
  !       SCOM    I       Signed number of commands and options
  !                       Negative means library only mode
  !       CCOM    C*(*)   Vocabulary
  !       VERSION C*(*)   Character string indicating the version number
  !                       and other relevant information
  !	#1	S.Guilloteau 	1-SEP-1989
  !		No log file in library only mode
  !---------------------------------------------------------------------
  character(len=*) :: lang          !
  character(len=*) :: help          !
  integer :: scom                   !
  character(len=*) :: ccom(1)       !
  character(len=*) :: version       !
  ! Local
  character(len=*), parameter :: rname='SIC_LOAD'
  integer :: jcom,ierr,i,ll
  logical :: error
  !
  ! First initialisations
  jcom = abs(scom)
  if (.not.loaded) then
    call sic_message(seve%f,rname,'SIC is not loaded, call SIC_OPT before')
    call sysexi(fatale)
  endif
  !
  ! Check the dimensions and language name
  ierr=0
  ! Check number of commands/options limit
  if (jcom+mbuilt(nlang).gt.mvocab)    ierr=ierr+1
  ! Check length of input commands
  if (len(ccom(1)).gt.command_length)  ierr=ierr+2
  ! Check number of languages
  if (nlang.ge.mlang)                  ierr=ierr+4
  ! Check language length
  ll = len_trim(lang)
  if (ll.gt.language_length)           ierr=ierr+8
  ! Check duplicate language name
  do i=1,nlang
    ! Ideally, should check LANGUAGES(I)%NAME(1:LL).EQ.LANG
    if (languages(i)%name.eq.lang)     ierr=ierr+16
  enddo
  if (ierr.ne.0) call fatal(ierr,lang)
  !
  ! Setup the "User" command language
  do i=1,jcom
    vocab(mbuilt(nlang)+i) = ccom(i)
  enddo
  nopt(0)          = mbuilt(nlang)+jcom
  nlang            = nlang+1
  mbuilt(nlang)    = nopt(0)
  languages(nlang)%name  = lang
  languages(nlang)%lname = ll
  languages(nlang)%help  = help
  languages(nlang)%prio  = 0        ! Means unset, automatic
  languages(nlang)%user  = .false.  ! Not a user language
  languages(nlang)%usym  => null()  ! No user language dictionary
  !
  ! Setup the options pointer for faster analysis
  call sic_load_options
  !
  ! Setup the internal short HELP when not in library only mode
  if (scom.le.0) then
    languages(nlang)%libmod = .true.
  else
    languages(nlang)%libmod = .false.
  endif
  languages(nlang)%mess = version
  !
  ! Recompute the language priorities
  error = .false.
  call parse_priority_recompute(error)
  if (error)  return
  !
end subroutine sic_load
!
subroutine fatal(ierr,lang)
  use sic_dependencies_interfaces
  use sic_interfaces, except_this=>fatal
  use gildas_def
  use sic_dictionaries
  use gbl_message
  !---------------------------------------------------------------------
  ! @ private
  !---------------------------------------------------------------------
  integer :: ierr                   !
  character(len=*) :: lang          !
  ! Local
  character(len=*), parameter :: rname='SIC'
  character(len=filename_length) :: mess
  !
  if (mod(ierr,2).eq.1) then
    write (mess,101) 'Language '//trim(lang)//' reached internal limit of ',  &
    mvocab,' total commands and options'
    call sic_message(seve%f,rname,mess)
    write (mess,101) 'This language can only define ',mvocab-mbuilt(nlang),  &
    ' commands or options'
    call sic_message(seve%f,rname,mess)
    if (ierr.eq.1) goto 999
    ierr = ierr-1
  endif
  if (mod(ierr,4).eq.2) then
    write(mess,101) 'Commands must be at most character * ',command_length
    call sic_message(seve%f,rname,mess)
    if (ierr.eq.2) goto 999
    ierr = ierr-2
  endif
  if (mod(ierr,8).eq.4) then
    call sic_message(seve%f,rname,'Too many languages')
    if (ierr.eq.4) goto 999
    ierr = ierr-4
  endif
  if (mod(ierr,16).eq.8) then
    write(mess,101) 'Language must be at most character * ',language_length
    call sic_message(seve%f,rname,mess)
    if (ierr.eq.8) goto 999
    ierr = ierr-8
  endif
  if (mod(ierr,32).eq.16) then
    call sic_message(seve%f,rname,'Duplicate language name '//lang)
    if (ierr.eq.16) goto 999
    ierr = ierr-16
  endif
  write (mess,101) 'Initialisation error number ',ierr
  call sic_message(seve%f,rname,mess)
999 call sic_message(seve%f,rname,'Language initialisation failure')
  call sysexi(fatale)
  !
101 format(a,i5,a)
end subroutine fatal
!
subroutine sic_loadcom(help,ccom,ctra,jcom,error)
  use sic_interfaces
  use sic_dependencies_interfaces
  use sic_dictionaries
  use gbl_message
  !---------------------------------------------------------------------
  ! @ no-interface (because of Ifort 9.0)
  !  Add a (list of) command(s) into a user language. Assume USER\
  ! language if no language is provided, define it if required. All
  ! other languages must have been defined before with DEFINE LANGUAGE
  !---------------------------------------------------------------------
  character(len=*), intent(in)    :: help     ! Logical name for help file
  character(len=*), intent(in)    :: ccom(*)  ! Vocabulary
  character(len=*), intent(in)    :: ctra(*)  ! Translation
  integer,          intent(in)    :: jcom     ! Number of commands in vocabulary
  logical,          intent(inout) :: error    ! Logical error flag
  ! Local
  character(len=*), parameter :: rname='DEFINE COMMAND'
  character(len=1), parameter :: backslash=char(92)
  character(len=language_length) :: lname,lnamef,langs(mlang)
  character(len=32) :: cname
  logical :: found
  integer :: i,j,kcom,icom,islash,jlang
  !
  ! 0) FixMe! Handle correctly jcom>1 !!!
  !    Input 'ccom' must be scalar in particular because of language
  !    resolution ('lnamef')
  if (jcom.gt.1) then
    call sic_message(seve%e,rname,  &
      'Internal error, not implemented for more than 1 command')
    error = .true.
    return
  endif
  !
  ! 1) Check if a language is provided
  islash = index(ccom(1),backslash)
  if (islash.eq.0) then
    lname = 'USER'
    if (.not. any(languages(1:nlang)%name.eq.lname)) then
      ! USER\ language does not exist yet
      call sic_define_language(lname,' ',error)
      if (error)  return
    endif
  else
    lname = ccom(1)(1:islash-1)
    call sic_upper(lname)
  endif
  !
  ! 2) Check if it is a known language
  langs(1:nlang) = languages(1:nlang)%name
  call sic_ambigs(rname,lname,lnamef,jlang,langs,nlang,error)
  if (error)  return
  if (.not.languages(jlang)%user) then
    ! This is not a user language
    call sic_message(seve%e,rname,  &
      trim(lnamef)//'\ is not a user language, can not append')
    error = .true.
    return
  endif
  !
  ! 3) Update the user command language
  !
  ! Check the dimensions and language name
  if (mbuilt(nlang)+jcom.gt.mvocab) then
    call sic_message(seve%e,rname,'Too many commands')
    error = .true.
    return
  endif
  !
  ! Check duplicate names
  icom = 0
  do i=1,jcom
    found = .false.
    !
    islash = index(ccom(i),backslash)
    if (islash.gt.0) then
      cname = " "//ccom(i)(islash+1:)
    else
      cname = " "//ccom(i)
    endif
    !
    if (len_trim(cname).gt.command_length) then
      call sic_message(seve%e,rname,'Command name '//trim(cname)//' too long')
      error = .true.
      return
    endif
    !
    do j=mbuilt(jlang-1)+1,mbuilt(jlang)
      if (vocab(j).eq.cname) then
        found = .true.
        exit  ! Loop
      endif
    enddo
    if (.not.found) icom = icom+1
  enddo
  !
  ! Push all commands after USER ones
  do i=mbuilt(nlang),mbuilt(jlang)+1,-1
    vocab(i+icom) = vocab(i)
  enddo
  !
  ! Update pointers after USER ones
  nopt(0) = mbuilt(nlang)+icom  ! Total number of commands and options
  do i=jlang+1,nlang
    mbuilt(i) = mbuilt(i)+icom  ! Index of the last command of the language
  enddo
  !
  ! Insert/replace USER\ commands
  do i=1,jcom
    found = .false.
    !
    islash = index (ccom(i),backslash) ! Locate the 
    !
    if (islash.gt.0) then
      cname = " "//ccom(i)(islash+1:)
    else
      cname = " "//ccom(i)
    endif
    !
    do j=mbuilt(jlang-1)+1,mbuilt(jlang)
      if (vocab(j).eq.cname) then
        call sic_message(seve%w,rname,'Overwriting '//trim(lnamef)//'\ command '//cname)
        kcom = j
        found = .true.
      endif
    enddo
    if (.not.found) then
      mbuilt(jlang)        = mbuilt(jlang)+1
      vocab(mbuilt(jlang)) = cname
      kcom                 = mbuilt(jlang)
    endif
    !
    ! Set the command help file. If not defined, use the language help file.
    if (help.ne.' ') then
      help_text(kcom) = help
    else
      help_text(kcom) = languages(jlang)%help
    endif
    !
    ! Save the translation into the appropriate user language
    call sic_symdict_set(languages(jlang)%usym,cname(2:),ctra(i),error)
    if (error)  return
  enddo
  !
  ! (Re)set the options pointers for faster analysis
  call sic_load_options
  !
end subroutine sic_loadcom
!
subroutine sic_define_language(name,help,error)
  use sic_dependencies_interfaces
  use sic_interfaces, except_this=>sic_define_language
  use sic_dictionaries
  use gbl_message
  !---------------------------------------------------------------------
  ! @ private
  ! Define a new user language
  !---------------------------------------------------------------------
  character(len=*), intent(in)    :: name   ! Language name
  character(len=*), intent(in)    :: help   ! Help file
  logical,          intent(inout) :: error  ! Logical error flag
  ! Local
  character(len=*), parameter :: rname='DEFINE LANGUAGE'
  integer :: lname,jlang,ier
  character(len=language_length) :: locname
  character(len=message_length) :: mess
  character(len=1), parameter :: backslash=char(92)
  !
  lname = len_trim(name)
  if (name(lname:lname).eq.backslash)  lname = lname-1
  !
  if (lname.gt.language_length) then
    write(mess,'(A,I2,A)')  &
      'Language name too long (max. ',language_length,' char.)'
    call sic_message(seve%e,rname,mess)
    error = .true.
    return
  endif
  !
  ! Setup the new user language
  if (nlang.ge.mlang) then
    call sic_message(seve%e,rname,'Too many languages')
    error = .true.
    return
  endif
  !
  locname = name(1:lname)
  call sic_upper(locname)
  !
  ! Protect against duplicate language name
  do jlang=1,nlang
    if (locname.eq.languages(jlang)%name) then
      call sic_message(seve%e,rname,"Duplicate language "//locname)
      error = .true.
      return
    endif
  enddo
  !
  nlang                  = nlang+1            ! Language index = total number of languages
  mbuilt(nlang)          = nopt(0)            ! Index of the last command of the language
  languages(nlang)%name  = locname            ! Language name
  languages(nlang)%lname = len_trim(locname)  ! Language length
  languages(nlang)%mess  = ' '                ! Short description
  languages(nlang)%help  = help               ! Help file
  languages(nlang)%prio  = 0                  ! Language priority set as automatic
  languages(nlang)%user  = .true.             ! It is a user language
  !
  ! Prepare its own dictionary of commands:
  allocate(languages(nlang)%usym,stat=ier)
  if (failed_allocate(rname,'dictionary',ier,error))  return
  call sic_symdict_init(languages(nlang)%usym,mucom,error)
  if (error)  return
  !
  ! Recompute the language priorities
  call parse_priority_recompute(error)
  if (error)  return
  !
  call sic_message(seve%d,rname,trim(locname)//'\ user language created')
  !
end subroutine sic_define_language
!
subroutine sic_load_options
  use sic_dependencies_interfaces
  use sic_interfaces, except_this=>sic_load_options
  use sic_dictionaries
  use gbl_message
  !---------------------------------------------------------------------
  ! @ private
  ! Setup or setup again the options pointer for faster analysis
  !---------------------------------------------------------------------
  ! Local
  character(len=*), parameter :: rname='SIC_LOAD'
  integer :: icom,k,jlang
  character(len=message_length) :: mess
  !
  hasopt(0) = 1  ! i.e. not 0 nor -1
  k = 0 ! Avoid initialization warning
  do icom=1,nopt(0)
    hasopt(icom) = 0
    if (vocab(icom)(1:1).ne.'/') then
      ! Found a new command
      k=icom
      !
      if (vocab(icom)(1:1).eq.'-')  then
        ! Command is declared with a leading "-": no options allowed at
        ! declaration time, but then any option at run time will be
        ! ignored (for e.g. HELP FOO /BAR)
        hasopt(k) = -1
      endif
      !
      jlang = 1
      do
        if (icom.le.mbuilt(jlang)) then
          ! Command is in language 'jlang'
          if (languages(jlang)%user) then
            ! 'jlang' is a user language. We can not forbid options for
            ! this command since the underlying command is unknown and can
            ! accept options.
            hasopt(k) = -1
          endif
          exit ! Loop
        endif
        jlang = jlang+1
      enddo
      !
      nopt(k)=0
    else
      ! Found an option of the current command
      if (hasopt(k).eq.-1) then
        mess = 'Command '//trim(vocab(icom)(2:))//' does not accept options'
        call sic_message(seve%f,rname,mess)
        call sysexi(fatale)
      endif
      hasopt(k) = +1
      nopt(k) = nopt(k)+1
    endif
  enddo
  !
end subroutine sic_load_options
!
subroutine sic_free_languages(error)
  use sic_interfaces, except_this=>sic_free_languages
  use sic_dictionaries
  !---------------------------------------------------------------------
  ! @ private
  ! Free the Sic languages
  !---------------------------------------------------------------------
  logical, intent(inout) :: error  !
  ! Local
  integer(kind=4) :: i,ier
  !
  do i=1,nlang
    if (languages(i)%user) then
      if (associated(languages(i)%usym)) then
        call sic_symdict_free(languages(i)%usym,error)
        ! if (error) continue
        deallocate(languages(i)%usym,stat=ier)
        if (ier.ne.0)  error=.true.
        ! if (error) continue
      endif
    endif
  enddo
  !
end subroutine sic_free_languages

