1#!/bin/sh 2# 3# Copy files from an Elftoolchain checkout and prepare them for import 4# into the NetBSD 'src' tree. 5# 6# Usage: 7# 8# netbsd-base-system-import.sh [-D] -s SRCDIR -d DISTDIR -m MODULE \ 9# [-m MODULE]... 10 11usage() { 12 echo "Usage: $0 [options]" 13 echo 14 echo "Prepare elftoolchain sources for importing into NetBSD src." 15 echo 16 echo "Options:" 17 echo " -D Only show diffs." 18 echo " -d DISTDIR Set the 'dist' directory for the elftoolchain import." 19 echo " Defaults to './dist'." 20 echo " -h Display this help text." 21 echo " -m MODULE A subdirectory of the elftoolchain tree to be" 22 echo " imported, e.g. 'libelf', 'common', 'libdwarf', etc." 23 echo " -s SRCDIR The 'trunk' directory of an elftoolchain checkout." 24 echo " -v Be verbose." 25} 26 27err() { 28 echo ERROR: "$@" 1>&2 29 echo 30 usage 31 exit 1 32} 33 34## Parse options. 35diff_only=NO 36verbose=NO 37options=":d:hs:m:vD" 38while getopts "$options" var; do 39 case $var in 40 d) dstdir="$OPTARG";; 41 h) usage; exit 0;; 42 m) modules="$OPTARG $modules";; 43 s) srcdir="$OPTARG";; 44 v) verbose=YES;; 45 D) diff_only=YES;; 46 '?') err "Unknown option: '-$OPTARG'.";; 47 ':') err "Option '-$OPTARG' expects an argument.";; 48 esac 49# shift $((OPTIND - 1)) 50done 51 52[ -n "${srcdir}" ] || err "Option -s must be specified." 53[ -n "${modules}" ] || err "Option -m must be specified at least once." 54 55if [ -z "${dstdir}" ]; then 56 dstdir="./dist" 57fi 58 59[ -d ${srcdir} ] || err "Missing source directory '$srcdir'." 60[ -d ${dstdir} ] || err "Missing destination directory '$dstdir'." 61 62# Verify that the source modules exist. 63for m in ${modules}; do 64 [ -d ${srcdir}/${m} ] || err "Missing source module '${srcdir}/${m}'" 65done 66 67## Helpers. 68rename_svn_id() { 69 sed -e '/\$Id:/ { 70 s/\$Id:/Id:/; 71 s/[ ]*\$// 72 }' 73} 74 75handle_block_comment() { 76 sed -e '/^\/\*-/ { i\ 77/* \$NetBSD\$ */\ 78 79}' 80} 81 82transform_placeholders() { 83 sed -e \ 84'/@ELFTC-DECLARE-DOWNSTREAM-VCSID@/ { 85c \ 86#if !defined(__RCSID)\ 87#define __RCSID(ID) /**/\ 88#endif /* !defined(__RCSID) */ 89}' -e \ 90'/@ELFTC-DEFINE-ELFTC-VCSID@/ { 91c \ 92#ifndef ELFTC_VCSID\ 93#define ELFTC_VCSID(ID) /**/\ 94#endif 95}' -e \ 96'/@ELFTC-USE-DOWNSTREAM-VCSID@/ { 97c \ 98__RCSID("$NetBSD: netbsd-base-system-import.sh,v 1.2 2024/03/03 17:37:34 christos Exp $"); 99}' -e \ 100'/@ELFTC-INCLUDE-SYS-CDEFS@/ { 101c \ 102#include <sys/cdefs.h> 103}' 104} 105 106# compare_and_move_or_diff filename generated_temp_file 107compare_and_move_or_diff() { 108 local dstfile=${dstdir}/${1} 109 110 egrep -v '\$NetBSD.*\$' ${2} > ${srccmptmp} 111 egrep -v '\$NetBSD.*\$' ${dstfile} > ${dstcmptmp} 2> /dev/null 112 113 if cmp -s ${srccmptmp} ${dstcmptmp}; then 114 return 0 115 fi 116 117 if [ "${diff_only}" = YES ]; then 118 # Show the changes needed to update the destination. 119 if [ -f ${dstfile} ]; then 120 diff -u ${dstfile} ${2} 121 else 122 echo '--- new file' ${file} 123 diff -u /dev/null ${2} 124 fi 125 else 126 mv ${2} ${dstfile} || exit ${?} 127 changed_file="${1}" 128 fi 129} 130 131# Manual pages need a CVS ID, and renaming of their SVN IDs. 132handle_manual_page() { 133 echo '.\" $NetBSD: netbsd-base-system-import.sh,v 1.2 2024/03/03 17:37:34 christos Exp $' > ${srctmp} 134 echo '.\"' >> ${srctmp} 135 rename_svn_id < ${srcdir}/${1} >> ${srctmp} 136 137 compare_and_move_or_diff ${1} ${srctmp} 138} 139 140# M4 files need a NetBSD RCS Id prepended, and any embedded 141# VCS IDs transformed. 142handle_m4_file() { 143 echo 'dnl $NetBSD: netbsd-base-system-import.sh,v 1.2 2024/03/03 17:37:34 christos Exp $' > ${srctmp} 144 transform_placeholders < ${srcdir}/${1} | \ 145 rename_svn_id >> ${srctmp} 146 147 compare_and_move_or_diff ${1} ${srctmp} 148} 149 150# Regular files only need their SVN IDs renamed. 151handle_regular_file() { 152 rename_svn_id < ${srcdir}/${1} > ${srctmp} 153 154 compare_and_move_or_diff ${1} ${srctmp} 155} 156 157# C sources need a NetBSD RCS Id prepended, the 158# ELFTC macros and SVN ids transformed. 159handle_c_source() { 160 handle_block_comment < ${srcdir}/${1} | \ 161 transform_placeholders | \ 162 rename_svn_id > ${srctmp} 163 164 compare_and_move_or_diff ${1} ${srctmp} 165} 166 167# Prepare temporary files. 168get_temporary_file() { 169 mktemp -p ${TMPDIR:-/tmp} -t import-et.XXXXXX 170} 171 172srctmp=`get_temporary_file` 173srccmptmp=`get_temporary_file` 174dstcmptmp=`get_temporary_file` 175 176trap "rm ${srctmp} ${srcmptmp} ${dstcmptmp};" 0 1 2 3 15 177 178# For each module: 179# - Create new directories in the destination. 180# - For each file in the source directory. 181# - Transform the source file to its imported content. 182# - Ignore files that differ only in RCS 183# - Display diffs or move changed files to the destination directory. 184 185for m in ${modules}; do 186 [ "$verbose" = YES ] && echo Examining module "'$m'". 187 188 # Create any new directories under the destination root. 189 (cd "${srcdir}" && find "${m}" -depth -type d) | \ 190 while read dir; do 191 [ "${verbose}" = YES ] && echo "Creating '$dir'." 192 mkdir -p "${dstdir}/${dir}" 193 done 194 195 # Import files, transforming them along the way. 196 (cd "${srcdir}" && find "${m}" -depth -type f $pattern) | \ 197 egrep -v '.o$|.a$|.po$|.so$|.swp$|*~$' | \ 198 while read file; do 199 changed_file='' # Set by 'compare_and_move_or_diff'. 200 201 if [ "${diff_only}" = NO ]; then 202 [ "${verbose}" = YES ] && echo -n "Importing file '$file'" 203 fi 204 205 case "${file##*/}" in 206 *.[0-9]) 207 handle_manual_page "${file}" 208 ;; 209 *.m4 ) 210 handle_m4_file "${file}" 211 ;; 212 Makefile | Version.map | *.m4 | *.mk) 213 handle_regular_file "${file}" 214 ;; 215 *.[ch]) 216 handle_c_source "${file}" 217 ;; 218 * ) error "Unsupported file: ${file}." 219 ;; 220 esac 221 222 if [ "${diff_only}" = NO -a "${verbose}" = YES ]; then 223 if [ -n "${changed_file}" ]; then 224 echo '- changed.' 225 else 226 echo '- unchanged.' 227 fi 228 fi 229 done 230done 231