aboutsummaryrefslogtreecommitdiff
path: root/tools/build-license-metadata.sh
diff options
context:
space:
mode:
Diffstat (limited to 'tools/build-license-metadata.sh')
-rwxr-xr-xtools/build-license-metadata.sh313
1 files changed, 313 insertions, 0 deletions
diff --git a/tools/build-license-metadata.sh b/tools/build-license-metadata.sh
new file mode 100755
index 0000000000..a138dbe7c4
--- /dev/null
+++ b/tools/build-license-metadata.sh
@@ -0,0 +1,313 @@
+#!/bin/sh
+
+set -u
+
+ME=$(basename $0)
+
+USAGE="Usage: ${ME} {options}
+
+Builds a license metadata specification and outputs it to stdout or {outfile}.
+
+The available options are:
+
+-k kind... license kinds
+-c condition... license conditions
+-p package... license package name
+-n notice... license notice file
+-d dependency... license metadata file dependency
+-t target... targets
+-m target:installed... map dependent targets to their installed names
+-is_container preserved dependent target name when given
+-o outfile output file
+"
+
+# Global flag variables
+license_kinds=
+license_conditions=
+license_package_name=
+license_notice=
+license_deps=
+targets=
+installmap=
+is_container=false
+ofile=
+
+# Global variables
+depfiles=" "
+effective_conditions=
+
+
+# Exits with a message.
+#
+# When the exit status is 2, assumes a usage error and outputs the usage message
+# to stderr before outputting the specific error message to stderr.
+#
+# Parameters:
+# Optional numeric exit status (defaults to 2, i.e. a usage error.)
+# Remaining args treated as an error message sent to stderr.
+die() {
+ lstatus=2
+ case "${1:-}" in *[^0-9]*) ;; *) lstatus="$1"; shift ;; esac
+ case "${lstatus}" in 2) echo "${USAGE}" >&2; echo >&2 ;; esac
+ if [ -n "$*" ]; then
+ echo -e "$*\n" >&2
+ fi
+ exit $lstatus
+}
+
+
+# Sets the flag variables based on the command-line.
+#
+# invoke with: process_args "$@"
+process_args() {
+ lcurr_flag=
+ while [ "$#" -gt '0' ]; do
+ case "${1}" in
+ -h)
+ echo "${USAGE}"
+ exit 0
+ ;;
+ -k)
+ lcurr_flag=kind
+ ;;
+ -c)
+ lcurr_flag=condition
+ ;;
+ -p)
+ lcurr_flag=package
+ ;;
+ -n)
+ lcurr_flag=notice
+ ;;
+ -d)
+ lcurr_flag=dependency
+ ;;
+ -t)
+ lcurr_flag=target
+ ;;
+ -m)
+ lcurr_flag=installmap
+ ;;
+ -o)
+ lcurr_flag=ofile
+ ;;
+ -is_container)
+ lcurr_flag=
+ is_container=true
+ ;;
+ -*)
+ die "Unknown flag: \"${1}\""
+ ;;
+ *)
+ case "${lcurr_flag}" in
+ kind)
+ license_kinds="${license_kinds}${license_kinds:+ }${1}"
+ ;;
+ condition)
+ license_conditions="${license_conditions}${license_conditions:+ }${1}"
+ ;;
+ package)
+ license_package_name="${license_package_name}${license_package_name:+ }${1}"
+ ;;
+ notice)
+ license_notice="${license_notice}${license_notice:+ }${1}"
+ ;;
+ dependency)
+ license_deps="${license_deps}${license_deps:+ }${1}"
+ ;;
+ target)
+ targets="${targets}${targets:+ }${1}"
+ ;;
+ installmap)
+ installmap="${installmap}${installmap:+ }${1}"
+ ;;
+ ofile)
+ if [ -n "${ofile}" ]; then
+ die "Output file -o appears twice as \"${ofile}\" and \"${1}\""
+ fi
+ ofile="${1}"
+ ;;
+ *)
+ die "Must precede argument \"${1}\" with type flag."
+ ;;
+ esac
+ ;;
+ esac
+ shift
+ done
+}
+
+# Reads a license metadata file from stdin, and outputs the named dependencies.
+#
+# No parameters.
+extract_deps() {
+ awk '$1 == "dep_name:" { sub(/^"/, "", $2); sub(/"$/, "", $2); print $2; }'
+}
+
+# Populates the depfiles variable identifying dependency files.
+#
+# Starting with the dependencies enumerated in license_deps, calculates the
+# transitive closure of all dependencies.
+#
+# Dependency names ending in .meta_module indirectly reference license
+# metadata with 1 license metadata filename per line.
+#
+# No parameters; no output.
+read_deps() {
+ lnewdeps=
+ for d in ${license_deps}; do
+ case "${d}" in
+ *.meta_module)
+ lnewdeps="${lnewdeps}${lnewdeps:+ }"$(cat "${d}") ;;
+ *)
+ lnewdeps="${lnewdeps}${lnewdeps:+ }${d}" ;;
+ esac
+ done
+ lnewdeps=$(echo "${lnewdeps}" | tr ' ' '\n' | sort -u)
+ lalldeps=
+ ldeps=
+ lmod=
+ ldep=
+ while [ "${#lnewdeps}" -gt '0' ]; do
+ ldeps="${lnewdeps}"
+ lnewdeps=
+ for ldep in ${ldeps}; do
+ depfiles="${depfiles}${ldep} "
+ lalldeps="${lalldeps}${lalldeps:+ }"$(cat "${ldep}" | extract_deps)
+ done
+ lalldeps=$(for d in ${lalldeps}; do echo "${d}"; done | sort -u)
+ for d in ${lalldeps}; do
+ ldeps="${d}"
+ case "${d}" in *.meta_module) ldeps=$(cat "${d}") ;; esac
+ for lmod in ${ldeps}; do
+ if ! expr "${depfiles}" : ".* ${lmod} .*" >/dev/null 2>&1; then
+ lnewdeps="${lnewdeps}${lnewdeps:+ }${lmod}"
+ fi
+ done
+ done
+ lalldeps=
+ done
+}
+
+# Returns the effective license conditions for the current license metadata.
+#
+# If a module is restricted or links in a restricted module, the effective
+# license has a restricted condition.
+calculate_effective_conditions() {
+ lconditions="${license_conditions}"
+ case "${license_conditions}" in
+ *restricted*) : do nothing ;;
+ *)
+ for d in ${depfiles}; do
+ if cat "${d}" | egrep -q 'effective_condition\s*:.*restricted' ; then
+ lconditions="${lconditions}${lconditions:+ }restricted"
+ break
+ fi
+ done
+ ;;
+ esac
+ echo "${lconditions}"
+}
+
+
+process_args "$@"
+
+if [ -n "${ofile}" ]; then
+ # truncate the output file before appending results
+ : >"${ofile}"
+else
+ ofile=/dev/stdout
+fi
+
+# spit out the license metadata file content
+(
+ echo 'license_package_name: "'${license_package_name}'"'
+ for kind in ${license_kinds}; do
+ echo 'license_kind: "'${kind}'"'
+ done
+ for condition in ${license_conditions}; do
+ echo 'license_condition: "'${condition}'"'
+ done
+ for f in ${license_notice}; do
+ echo 'license_text: "'${f}'"'
+ done
+ echo "is_container: ${is_container}"
+ for t in ${targets}; do
+ echo 'target: "'${t}'"'
+ done
+ for m in ${installmap}; do
+ echo 'install_map: "'${m}'"'
+ done
+) >>"${ofile}"
+read_deps
+effective_conditions=$(calculate_effective_conditions)
+for condition in ${effective_conditions}; do
+ echo 'effective_condition: "'${condition}'"'
+done >>"${ofile}"
+for dep in ${depfiles}; do
+ echo 'dep {'
+ cat "${dep}" | \
+ awk -v name="${dep}" '
+ function strip_type() {
+ $1 = ""
+ sub(/^\s*/, "")
+ }
+ BEGIN {
+ print " dep_name: " name
+ }
+ $1 == "license_package_name:" {
+ strip_type()
+ print " dep_package_name: "$0
+ }
+ $1 == "dep_name:" {
+ print " dep_sub_dep: "$2
+ }
+ $1 == "license_kind:" {
+ print " dep_license_kind: "$2
+ }
+ $1 == "license_condition:" {
+ print " dep_license_condition: "$2
+ }
+ $1 == "is_container:" {
+ print " dep_is_container: "$2
+ }
+ $1 == "license_text:" {
+ strip_type()
+ print " dep_license_text: "$0
+ }
+ $1 == "target:" {
+ print " dep_target: "$2
+ }
+ $1 == "install_map:" {
+ print " dep_install_map: "$2
+ }
+ '
+ # The restricted license kind is contagious to all linked dependencies.
+ dep_conditions=$(echo $(
+ cat "${dep}" | awk '
+ $1 == "effective_condition:" {
+ $1 = ""
+ sub(/^\s*/, "")
+ gsub(/"/, "")
+ print
+ }
+ '
+ ))
+ for condition in ${dep_conditions}; do
+ echo ' dep_effective_condition: "'${condition}'"'
+ done
+ if ! ${is_container}; then
+ case "${dep_conditions}" in
+ *restricted*) : already restricted -- nothing to inherit ;;
+ *)
+ case "${effective_conditions}" in
+ *restricted*)
+ # "contagious" restricted infects everything linked to restricted
+ echo ' dep_effective_condition: "restricted"'
+ ;;
+ esac
+ ;;
+ esac
+ fi
+ echo '}'
+done >>"${ofile}"