1#!/usr/bin/awk -f 2# 3# Combine multiple pkg-plist files into a single pkg-plist. 4# 5# This takes a list of all options as command line arguments. The 6# order of the options determines the order option specific plist 7# entries appear in the combined output. 8# 9# The plists must be fed into stdin and preceded by a line starting 10# with `OPTIONS:` followed by a white space separated list of the 11# active options. 12# 13# Files that appear with all options are listed first, followed by 14# the option specific output. 15# 16# @param ARGV 17# A sorted list of options 18# 19 20# Get the order of options 21BEGIN { 22 OPTION_STR["DOCS"] = "%%PORTDOCS%%" 23 OPTION_STR["EXAMPLES"] = "%%PORTEXAMPLES%%" 24 for (i = 1; i < ARGC; ++i) { 25 OPTIONS_ORDERD[i] = ARGV[i] 26 CNT_OPT_FILES[ARGV[i]] = 0 27 if (!(ARGV[i] in OPTION_STR)) { 28 OPTION_STR[ARGV[i]] = "%%" ARGV[i] "%%" 29 } 30 if (!("NO_" ARGV[i] in OPTION_STR)) { 31 OPTION_STR["NO_" ARGV[i]] = "%%NO_" ARGV[i] "%%" 32 } 33 delete ARGV[i] 34 } 35 CNT_FILES = 0 36} 37 38# Get the options the following files were staged with 39/^OPTIONS:/ { 40 delete aoptions 41 sub(/^OPTIONS: */, "") 42 cnt_aoptions = split($0, aoptions) 43 for (i = 1; i <= cnt_aoptions; ++i) { 44 ++OPTIONS[aoptions[i]] 45 } 46 ++CONFIGS 47 next 48} 49 50# Collect files 51{ 52 # Record order of file 53 if (!($0 in FILES)) { 54 FILES_ORDERED[++CNT_FILES] = $0 55 } 56 # Count occurence of file 57 ++FILES[$0] 58 # The same book keepin per option 59 for (i = 1; i <= cnt_aoptions; ++i) { 60 option = aoptions[i] 61 # Record order of file for option 62 if (!OPT_FILES[option, $0]) { 63 OPT_FILES_ORDERED[option, ++CNT_OPT_FILES[option]] = $0 64 } 65 # Count occurence of file by option 66 ++OPT_FILES[option, $0] 67 } 68} 69 70# Print files 71END { 72 # Print files common to all configurations 73 for (i = 1; i <= CNT_FILES; ++i) { 74 file = FILES_ORDERED[i] 75 if (FILES[file] == CONFIGS) { 76 print file 77 delete FILES[file] 78 } 79 } 80 # Print option specific files 81 for (i = 1; OPTIONS_ORDERD[i]; ++i) { 82 option = OPTIONS_ORDERD[i] 83 for (p = 1; p <= CNT_OPT_FILES[option]; ++p) { 84 file = OPT_FILES_ORDERED[option, p] 85 # Skip files that have already been printed 86 if (!(file in FILES)) { continue } 87 # Print file if it only occurs for the current 88 # option 89 if (OPT_FILES[option, file] == OPTIONS[option] && 90 OPT_FILES[option, file] == FILES[file]) { 91 print OPTION_STR[option] file 92 delete FILES[file] 93 } 94 } 95 for (p = 1; p <= CNT_FILES; ++p) { 96 file = FILES_ORDERED[p] 97 if (!(file in FILES)) { continue } 98 # Print file if it occurs everywhere but with 99 # this option 100 if (!OPT_FILES[option, file] && 101 FILES[file] + OPTIONS[option] == CONFIGS) { 102 print OPTION_STR["NO_" option] file 103 delete FILES[file] 104 } 105 } 106 } 107 # Print all files that have not been printed 108 for (i = 1; i <= CNT_FILES; ++i) { 109 file = FILES_ORDERED[i] 110 if (!(file in FILES)) { continue } 111 print "@fail " file " could not be mapped to an option!" 112 msg = "@fail Candidates:" 113 for (p = 1; OPTIONS_ORDERD[p]; ++p) { 114 if (OPT_FILES[OPTIONS_ORDERD[p], file]) { 115 msg = msg " " OPTIONS_ORDERD[p] 116 } 117 } 118 print msg 119 } 120} 121