# This file is part of the YAZ toolkit
# Copyright (C) Index Data
# See the file LICENSE for details.
#
#
# Converts a CSV file with Object identifiers to C

proc readoids {input} {
    set csv [open $input r]
    set lineno 0

    while {1} {
	incr lineno
	set cnt [gets $csv line]
	if {$cnt < 0} {
	    break
	}
	if {![string compare [string index $line 0] \"]} {
	    continue
	}
	set tokens [string map {, { }} $line]
	if {[llength $tokens] != 3} {
	    puts "$input:$lineno: Bad line '$line'"
	    exit 1
	}
	lappend oids $tokens
    }
    close $csv
    if {![info exists oids]} {
	puts "$input:0 No OIDS"
	exit 1
    }
    return $oids
}

proc constant_var {oid} {
    set lname [string tolower [lindex $oid 2]]
    set lname [string map {- _ . _ { } _ ( {} ) {}} $lname]
    set prefix [string tolower [lindex $oid 0]]

    return yaz_oid_${prefix}_${lname}
}

proc oid_to_xml {input xname} {
    set oids [readoids "${input}"]
    set xfile [open "${xname}" w]

    puts $xfile "<!-- Generated by oidtoc.tcl from $input -->"
    puts $xfile {<informaltable id="standard-oids">}
    puts $xfile {<tgroup cols="3">}
    puts $xfile {<colspec colwidth="3*" colname="name"></colspec>}
    puts $xfile {<colspec colwidth="2*" colname="class"></colspec>}
    puts $xfile {<colspec colwidth="4*" colname="oid"></colspec>}
    puts $xfile {<thead>}
    puts $xfile {<row>}
    puts $xfile {<entry>Name</entry>}
    puts $xfile {<entry>Class</entry>}
    puts $xfile {<entry>Constant / OID</entry>}
    puts $xfile {</row>}
    puts $xfile {</thead>}
    puts $xfile {<tbody>}

    foreach oid $oids {
	puts $xfile {<row>}

	puts $xfile {<entry morerows="1">}
	puts $xfile [lindex $oid 2]
	puts $xfile {</entry>}


	puts $xfile {<entry morerows="1">}
	puts $xfile [lindex $oid 0]
	puts $xfile {</entry>}

	puts $xfile {<entry><literal>}
	set v [constant_var $oid]
	puts $xfile $v
	puts $xfile {</literal></entry>}


	puts $xfile {</row>}
	puts $xfile {<row>}

	puts $xfile {<entry namest="oid">}
	puts $xfile [lindex $oid 1]
	puts $xfile {</entry>}

	puts $xfile {</row>}
    }

    puts $xfile {</tbody>}
    puts $xfile {</tgroup>}

    puts $xfile {</informaltable>}
    close $xfile
}

proc oid_to_c {input cname hname} {
    set oids [readoids "${input}"]

    set cfile [open ${cname} w]
    set hfile [open ${hname} w]

    puts $cfile "/** \\file [file tail $cname]"
    puts $hfile "/** \\file [file tail $hname]"
    set preamble "    \\brief Standard Object Identifiers: Generated from $input */"
    puts $cfile $preamble
    puts $hfile $preamble
    puts $hfile "\#ifndef OID_STD_H"
    puts $hfile "\#define OID_STD_H"

    puts $cfile "\#if HAVE_CONFIG_H"
    puts $cfile "\#include <config.h>"
    puts $cfile "\#endif"

    puts $cfile "\#include <yaz/oid_db.h>"
    puts $cfile ""
    # To avoid LNK4049
    puts $hfile "\#ifdef YAZ_DLL"
    puts $hfile "\#define OID_EXPORT YAZ_EXPORT"
    puts $hfile "\#else"
    puts $hfile "\#define OID_EXPORT YAZ_IMPORT"
    puts $hfile "\#endif"

    puts $hfile "YAZ_BEGIN_CDECL"
    foreach oid $oids {

	set v [constant_var $oid]

	puts -nonewline $cfile "YAZ_EXPORT const Odr_oid $v\[\] = \{"
	puts -nonewline $cfile [string map {. ,} [lindex $oid 1]]
	puts $cfile ",-1\};"

	puts $hfile "OID_EXPORT extern const Odr_oid $v\[\];"
    }

    puts $cfile "YAZ_EXPORT struct yaz_oid_entry yaz_oid_standard_entries\[\] ="
    puts $cfile "\{"
    foreach oid $oids {
	set v [constant_var $oid]

	puts -nonewline $cfile "\t\{CLASS_[lindex $oid 0], "
	puts -nonewline $cfile "$v, "
	puts -nonewline $cfile \"[lindex $oid 2]\"
	puts $cfile "\},"
    }

    puts $cfile "\t\{CLASS_NOP, 0, 0\}"
    puts $cfile "\};"

    puts $hfile "OID_EXPORT extern struct yaz_oid_entry yaz_oid_standard_entries\[\];"
    puts $hfile "YAZ_END_CDECL"
    puts $hfile "\#endif"
    close $cfile
    close $hfile
}

if {[llength $argv] == 3} {
    oid_to_c [lindex $argv 0] [lindex $argv 1] [lindex $argv 2]
} elseif {[llength $argv] == 2} {
    oid_to_xml [lindex $argv 0] [lindex $argv 1]
} else {
    puts "oidtoc.tcl csv cfile hfile"
    exit 1
}
