#
# Copyright (c) 2010-2014,2017,2020,2022 LAAS/CNRS
# All rights reserved.
#
# Redistribution  and  use  in  source  and binary  forms,  with  or  without
# modification, are permitted provided that the following conditions are met:
#
#   1. Redistributions of  source  code must retain the  above copyright
#      notice and this list of conditions.
#   2. Redistributions in binary form must reproduce the above copyright
#      notice and  this list of  conditions in the  documentation and/or
#      other materials provided with the distribution.
#
# THE SOFTWARE  IS PROVIDED "AS IS"  AND THE AUTHOR  DISCLAIMS ALL WARRANTIES
# WITH  REGARD   TO  THIS  SOFTWARE  INCLUDING  ALL   IMPLIED  WARRANTIES  OF
# MERCHANTABILITY AND  FITNESS.  IN NO EVENT  SHALL THE AUTHOR  BE LIABLE FOR
# ANY  SPECIAL, DIRECT,  INDIRECT, OR  CONSEQUENTIAL DAMAGES  OR  ANY DAMAGES
# WHATSOEVER  RESULTING FROM  LOSS OF  USE, DATA  OR PROFITS,  WHETHER  IN AN
# ACTION OF CONTRACT, NEGLIGENCE OR  OTHER TORTIOUS ACTION, ARISING OUT OF OR
# IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
#
#                                           Anthony Mallet on Tue Jan 12 2010
#

#/
# Mappings template
# -----------------

# Template for type mappings generation.

template usage "Mappings generation template\n" [regsub -all [join {
  { *#/? ?} {----} {[*+]([^*+\n]+)[*+]} {::} { ::\n}
} |] {
  #/ This template generates a source file containing the native type
  # definitions for all IDL types defined in the .gen input file. By default,
  # types are generated for the codels language (defined in the .gen file) for
  # the first available component. This can be changed with the -l option. The
  # generated mappings are output on stdout.
  #
  # Additionnaly, a dependency file suitable for inclusion in a `Makefile` can
  # be generated. This is controlled by the `-MD`, `-MF` and `-MT`
  # options. These options are documented herafter, and follow the same syntax
  # as the same options of `gcc`.
  #
  # === Example
  # ----
  # user@host:~$ genom3 mappings demo.gen > demo_c_types.h
  # user@host:~$ genom3 mappings -l c++ demo.gen > demo_cxx_types.h
  # ----
  #
  # === Supported options
  #
  # +-l+::
  # +--language=lang+ ::
  #	Generate mappings for language 'lang'
  # +--signature+ ::
  #	Generate codel signatures in addition to types mappings
  # +-MD+ ::
  #		Generate dependency information (in out.d)
  # +-MF='file'+ ::
  #	Generate dependency in 'file' instead of out.d
  # +-MT='target'+ ::
  #	Change the target of the dependency rules
  # +-h+::
  # +--help+ ::
  #		Print usage summary (this text)
} {\1}]

# defaults
variable sign		off
variable deps		off
variable dfile		"out.d"
variable dtarget	""
engine mode +silent

# parse options
template options {
	 --signature	{ set sign on }
    -l - --language	{ set lang [template arg] }
    -MD			{ set deps on }
    -MF			{ set dfile [template arg] }
    -MT			{ set dtarget [template arg] }
    -h - --help		{ puts [template usage]; exit 0 }
}

# check/process input files
if {![llength $argv]} { puts [template usage]; exit 2 }
dotgen parse file {*}$argv

# build header
set header " Generated by [dotgen genom version]. Do not edit.\n"
append header " Source file: $argv\n"
if {![catch {dotgen input notice} notice]} {
  append header $notice
}
set out [comment $header]

# set default language
if {![info exists lang]} {
  foreach c [dotgen components] {
    set lang [$c language]
    break
  }
}
if {![info exists lang]} {
  template fatal "no default language, please set one with --language"
}
lang $lang

# get types and codels if needed
set objs [dotgen types]
if {$sign} {
  foreach comp [list {*}[dotgen components] {*}[dotgen interfaces]] {
    lappend objs {*}[lmap c [$comp codels] {
      expr {[$c loc context] == $comp ? $c : [continue]}
    }]
  }
}

# generate definitions
template parse string [language mapping $objs] string mappings
append out "\n$mappings"

# dependencies
if {$dtarget == ""} { set dtarget $out }
if {$deps} {
  set deps [list]
  foreach d [concat [dotgen input deps] [template deps]] {
    lappend deps "$dtarget: $d"
    lappend deps "$d:"
  }
  engine mode +overwrite -move-if-change
  template parse raw [join $deps "\n"]\n file $dfile
}

puts $out
