mulle-mingw-dumpdef.sh
9514a7cb
 #! /bin/sh
ec2b9bc2
 #
 #   Copyright (c) 2016 Nat! - Mulle kybernetiK
 #   All rights reserved.
 #
 #   Redistribution and use in source and binary forms, with or without
 #   modification, are permitted provided that the following conditions are met:
 #
 #   Redistributions of source code must retain the above copyright notice, this
 #   list of conditions and the following disclaimer.
 #
 #   Redistributions in binary form must reproduce the above copyright notice,
 #   this list of conditions and the following disclaimer in the documentation
 #   and/or other materials provided with the distribution.
 #
 #   Neither the name of Mulle kybernetiK nor the names of its contributors
 #   may be used to endorse or promote products derived from this software
 #   without specific prior written permission.
 #
 #   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
 #   AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 #   IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 #   ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
 #   LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
 #   CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
 #   SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
 #   INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
 #   CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 #   ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 #   POSSIBILITY OF SUCH DAMAGE.
 #
9514a7cb
 VERSION=0.0
ec2b9bc2
 
1ef270ea
 PATH="/usr/local/libexec/mulle-bootstrap:/usr/bin:$PATH"
ec2b9bc2
 export PATH
 
9514a7cb
 INDENT="${INDENT:-"   "}"
 DATA="${DATA:-"DATA"}"
ec2b9bc2
 
 
 usage()
 {
    echo "failed" >&2
    exit 1
 }
 
 
1ef270ea
 #
 # search path delimited by LF
 #
 find_library_in_directories()
 {
    local filename
    local directories
 
    filename="$1"
    directories="$2"
 
    local directory
    local path
 
fcf4306a
    [ -z "${DEFAULT_IFS}" ] && internal_fail "IFS fail"
 
5c06c0e8
    IFS="
 "
1ef270ea
    for directory in ${directories}
    do
5c06c0e8
       IFS="${DEFAULT_IFS}"
 
1ef270ea
       path="${directory}/${filename}"
 
       if [ -f "${path}" ]
       then
          echo "${path}"
          break
       fi
    done
 
5c06c0e8
    IFS="${DEFAULT_IFS}"
1ef270ea
 }
 
 
 find_library()
 {
    local filename
 
    filename="$1"
 
    if [ -f "${filename}" ]
    then
       echo "${filename}"
       return
bcff535a
    fi
1ef270ea
 
    case "${filename}" in
       ?:/*)
          filename="`echo "/${filename}" | sed 's|\\|/|g' | sed 's|:|/|'`"
          find_library "${filename}"
       ;;
 
       ~*|.*|/*|"")
          :
       ;;
 
       *)
          find_library_in_directories "${filename}" "${SEARCH_PATH}"
       ;;
    esac
 }
 
 
9514a7cb
 dump_function_exports()
ec2b9bc2
 {
bcff535a
    local filename
ec2b9bc2
 
9514a7cb
    filename="$1"
    dumpbin.exe -symbols "${filename}" | egrep '^[^|]* \(\) [^|]*\|' | fgrep ' External ' | fgrep -v ' UNDEF ' | sed 's/^[^|]*| *\([^ (]*\).*$/\1/' | sed 's/^_//' | sort
 }
ec2b9bc2
 
 
9514a7cb
 dump_data_exports()
 {
bcff535a
    local filename
9514a7cb
 
    filename="$1"
    dumpbin.exe -symbols "${filename}" | egrep -v '^[^|]* \(\) [^|]*\|' | fgrep ' External ' | fgrep -v ' UNDEF ' | sed "s/^[^|]*| *\\([^ (]*\\).*\$/\\1   ${DATA}/" | sed 's/^_//' | sort
 }
 
 
 dump_exports()
 {
bcff535a
    local filename
9514a7cb
 
    filename="$1"
 
    local functions
    local data
 
    functions="`dump_function_exports "${filename}"`"
    data="`dump_data_exports "${filename}"`"
 
    cat <<EOF
 ${functions}
 
 ${data}
 EOF
ec2b9bc2
 }
 
 
 dump_library()
 {
    local prefixes
bcff535a
    local filename
ec2b9bc2
 
    prefixes="$1"
    shift
9514a7cb
 
    libraryname="$1"
ec2b9bc2
    shift
 
9514a7cb
    [ -z "${libraryname}" ] && echo "empty libraryname" >&2 && exit 1
 
    local filename
 
    filename="`find_library ${libraryname}`"
    if [ -z "${filename}" ]
    then
       filename="`find_library ${libraryname}.lib`"
       if [ -z "${filename}" ]
       then
          echo "${libraryname} ($PWD) not found" >&2 && exit 1
       fi
    fi
 
ec2b9bc2
    if [ ! -z "${prefixes}" ]
    then
1ef270ea
       if [ ! -z "${VERBOSE}" ]
       then
9514a7cb
          echo "Dumping `basename -- ${filename}` symbols with prefixes ${prefixes}" >&2
1ef270ea
       fi
9514a7cb
       dump_exports "${filename}" | egrep "${prefixes}"
ec2b9bc2
    else
1ef270ea
       if [ ! -z "${VERBOSE}" ]
       then
9514a7cb
          echo "Dumping all `basename -- ${filename}` symbols" >&2
1ef270ea
       fi
bcff535a
       dump_exports "${filename}"
ec2b9bc2
    fi
 }
 
 
 dump_libraries()
 {
    local name
    local prefixes
 
    name="$1"
    shift
    prefixes="$1"
    shift
 
    if [ $# -eq 0 ]
    then
       echo "no files to dump" >&2
       exit 1
    fi
 
    if [ -z "${SUPPRESS_HEADER}" ]
bcff535a
    then
       if [ ! -z "${name}" ]
       then
          echo "LIBRARY ${name}"
       fi
       echo "EXPORTS"
ec2b9bc2
    fi
 
    while [ $# -ne 0 ]
    do
1ef270ea
       dump_library "${prefixes}" "$1" | sed "s/^\\(.*\\)\$/${INDENT}\\1/"
ec2b9bc2
       shift
    done
 }
 
 
 main()
 {
    local outfile
    local prefixes
9514a7cb
    local cpp_stringprefix
ec2b9bc2
    local name
 
128e6b71
    name=
ec2b9bc2
    prefixes=
    outfile=
19b16123
    SEARCH_PATH="."
9514a7cb
    cpp_stringprefix=
ec2b9bc2
 
    while [ $# -ne 0 ]
    do
       case "$1" in
          -o|--output)
             shift
             outfile="$1"
          ;;
 
1ef270ea
          -d|--directory)
             shift
             SEARCH_PATH="$1
 ${SEARCH_PATH}"
          ;;
 
9514a7cb
          --cpp-strings)
58ddf0fd
             cpp_stringprefix='^\?\?_C|'
ec2b9bc2
          ;;
 
66380d87
          --suppress_header)
ec2b9bc2
             SUPPRESS_HEADER=YES
          ;;
bcff535a
 
66380d87
          -n|--name)
ec2b9bc2
             shift
             name="$1"
          ;;
 
          -p|--prefix)
             shift
             if [ -z "${prefixes}" ]
             then
58ddf0fd
                prefixes="${cpp_stringprefix}^_*$1"
ec2b9bc2
             else
1ef270ea
                prefixes="${prefixes}|^_*$1"
ec2b9bc2
             fi
          ;;
 
          -sp|--strict-prefix)
             shift
             if [ -z "${prefixes}" ]
             then
1ef270ea
                prefixes="^$1"
ec2b9bc2
             else
1ef270ea
                prefixes="${prefixes}|^$1"
ec2b9bc2
             fi
          ;;
 
9514a7cb
          --version)
             echo "$VERSION"
             exit 0
          ;;
 
1ef270ea
          -v|--verbose)
             VERBOSE=YES
          ;;
 
ec2b9bc2
          -*)
fcf4306a
             echo "mulle-mingw-dumpdef.sh: Unknown option $1" >&2
ec2b9bc2
             usage
          ;;
 
          *)
             break
          ;;
       esac
 
       shift
    done
 
    local libname
 
128e6b71
    if [ ! -z "${name}" ]
    then
       libname="`basename "${name:-$1}"`"
       libname="`echo "${libname}" | sed 's/^\([^.]*\)*\\..*$/\1/'`"
ec2b9bc2
 
128e6b71
       [ -z "${libname}" ] && echo "could not figure out library name from \"${name:-$1}\"" >&2 && exit 1
    fi
04828dc6
 
ec2b9bc2
    if [ ! -z "${outfile}" ]
    then
bcff535a
       trap "rm ${outfile}" INT TERM
9514a7cb
 
1ef270ea
       dump_libraries "${libname}" "${prefixes}" "$@"  | unix2dos > "${outfile}"
       if [ ! -z "${VERBOSE}" ]
       then
          echo "Dumped to ${outfile}" >&2
       fi
ec2b9bc2
    else
1ef270ea
       dump_libraries "${libname}" "${prefixes}" "$@"
ec2b9bc2
    fi
 }
 
 main "$@"