1847a0c37SPatrick Williams#!/usr/bin/env bash 2847a0c37SPatrick Williams 3847a0c37SPatrick Williamsset -e 4847a0c37SPatrick Williams 5*a4c9edc1SPatrick Williams# Locale can change behavior of utilities like 'sort' but we want the output 6*a4c9edc1SPatrick Williams# to be stable on all machines. Force the locale to 'C' for consistency. 7*a4c9edc1SPatrick Williamsexport LC_ALL=C 8*a4c9edc1SPatrick Williams 9847a0c37SPatrick Williamsfunction show_usage { 10847a0c37SPatrick Williams cat \ 11847a0c37SPatrick Williams<<EOF 12847a0c37SPatrick WilliamsUsage: $(basename "$0") [options] <command-args>* 13847a0c37SPatrick Williams 14847a0c37SPatrick WilliamsGenerate meson.build files from a directory tree containing YAML files and 15847a0c37SPatrick Williamsfacilitate building the sdbus++ sources. 16847a0c37SPatrick Williams 17847a0c37SPatrick WilliamsOptions: 18847a0c37SPatrick Williams --help - Display this message 19847a0c37SPatrick Williams --command <cmd> - Command mode to execute (default 'meson'). 20847a0c37SPatrick Williams --directory <path> - Root directory of the YAML source (default '.'). 21847a0c37SPatrick Williams --output <path> - Root directory of the output (default '.'). 22847a0c37SPatrick Williams --tool <path> - Path to the processing tool (default 'sdbus++'). 23847a0c37SPatrick Williams --version - Display this tool's version string. 24847a0c37SPatrick Williams 25847a0c37SPatrick WilliamsCommands: 26847a0c37SPatrick Williams meson - Generate a tree of meson.build files corresponding 27847a0c37SPatrick Williams to the source YAML files. 28847a0c37SPatrick Williams cpp <intf> - Generate the source files from a YAML interface. 29847a0c37SPatrick Williams markdown <intf> - Generate the markdown files from a YAML interface. 30847a0c37SPatrick Williams version - Display this tool's version string. 31847a0c37SPatrick Williams 32847a0c37SPatrick WilliamsEOF 33847a0c37SPatrick Williams} 34847a0c37SPatrick Williams 35847a0c37SPatrick Williams## The version is somewhat arbitrary but is used to create a warning message 36847a0c37SPatrick Williams## if a repository contains old copies of the generated meson.build files and 37847a0c37SPatrick Williams## needs an update. We should increment the version number whenever the 38847a0c37SPatrick Williams## resulting meson.build would change. 39847a0c37SPatrick Williamstool_version="sdbus++-gen-meson version 1" 40847a0c37SPatrick Williamsfunction show_version { 41847a0c37SPatrick Williams echo "$tool_version" 42847a0c37SPatrick Williams} 43847a0c37SPatrick Williams 44847a0c37SPatrick Williams# Set up defaults. 45847a0c37SPatrick Williamssdbuspp="sdbus++" 46847a0c37SPatrick Williamsoutputdir="." 47847a0c37SPatrick Williamscmd="meson" 48847a0c37SPatrick Williamsrootdir="." 49847a0c37SPatrick Williams 50847a0c37SPatrick Williams# Parse options. 51847a0c37SPatrick Williamsoptions="$(getopt -o hc:d:o:t:v --long help,command:,directory:,output:,tool:,version -- "$@")" 52847a0c37SPatrick Williamseval set -- "$options" 53847a0c37SPatrick Williams 54847a0c37SPatrick Williamswhile true; 55847a0c37SPatrick Williamsdo 56847a0c37SPatrick Williams case "$1" in 57847a0c37SPatrick Williams -h | --help) 58847a0c37SPatrick Williams show_usage 59847a0c37SPatrick Williams exit 60847a0c37SPatrick Williams ;; 61847a0c37SPatrick Williams 62847a0c37SPatrick Williams -c | --command) 63847a0c37SPatrick Williams shift 64847a0c37SPatrick Williams cmd="$1" 65847a0c37SPatrick Williams shift 66847a0c37SPatrick Williams ;; 67847a0c37SPatrick Williams 68847a0c37SPatrick Williams -d | --directory) 69847a0c37SPatrick Williams shift 70847a0c37SPatrick Williams rootdir="$1" 71847a0c37SPatrick Williams shift 72847a0c37SPatrick Williams ;; 73847a0c37SPatrick Williams 74847a0c37SPatrick Williams -o | --output) 75847a0c37SPatrick Williams shift 76847a0c37SPatrick Williams outputdir="$1" 77847a0c37SPatrick Williams shift 78847a0c37SPatrick Williams ;; 79847a0c37SPatrick Williams 80847a0c37SPatrick Williams -t | --tool) 81847a0c37SPatrick Williams shift 82847a0c37SPatrick Williams sdbuspp="$1" 83847a0c37SPatrick Williams shift 84847a0c37SPatrick Williams ;; 85847a0c37SPatrick Williams 86847a0c37SPatrick Williams -v | --version) 87847a0c37SPatrick Williams show_version 88847a0c37SPatrick Williams exit 89847a0c37SPatrick Williams ;; 90847a0c37SPatrick Williams 91847a0c37SPatrick Williams --) 92847a0c37SPatrick Williams shift 93847a0c37SPatrick Williams break 94847a0c37SPatrick Williams ;; 95847a0c37SPatrick Williams esac 96847a0c37SPatrick Williamsdone 97847a0c37SPatrick Williams 98847a0c37SPatrick Williams## Create an initially empty meson.build file. 99847a0c37SPatrick Williams## $1 - path to create meson.build at. 100847a0c37SPatrick Williamsfunction meson_empty_file { 101847a0c37SPatrick Williams mkdir -p "$1" 102847a0c37SPatrick Williams echo "# Generated file; do not modify." > "$1/meson.build" 103847a0c37SPatrick Williams} 104847a0c37SPatrick Williams 105847a0c37SPatrick Williams## Create the root-level meson.build 106847a0c37SPatrick Williams## 107847a0c37SPatrick Williams## Inserts rules to run the available version of this tool to ensure the 108847a0c37SPatrick Williams## version has not changed. 109847a0c37SPatrick Williamsfunction meson_create_root { 110847a0c37SPatrick Williams meson_empty_file "$outputdir" 111847a0c37SPatrick Williams 112847a0c37SPatrick Williams cat >> "$outputdir/meson.build" \ 113847a0c37SPatrick Williams<<EOF 114847a0c37SPatrick Williamssdbuspp_gen_meson_ver = run_command( 115847a0c37SPatrick Williams sdbuspp_gen_meson_prog, 116847a0c37SPatrick Williams '--version', 117847a0c37SPatrick Williams).stdout().strip().split('\n')[0] 118847a0c37SPatrick Williams 119847a0c37SPatrick Williamsif sdbuspp_gen_meson_ver != '$tool_version' 120847a0c37SPatrick Williams warning('Generated meson files from wrong version of sdbus++-gen-meson.') 121847a0c37SPatrick Williams warning( 122847a0c37SPatrick Williams 'Expected "$tool_version", got:', 123847a0c37SPatrick Williams sdbuspp_gen_meson_ver 124847a0c37SPatrick Williams ) 125847a0c37SPatrick Williamsendif 126847a0c37SPatrick Williams 127847a0c37SPatrick WilliamsEOF 128847a0c37SPatrick Williams} 129847a0c37SPatrick Williams 130847a0c37SPatrick Williams## hash-tables to store: 131847a0c37SPatrick Williams## meson_paths - list of subdirectory paths for which an empty meson.build 132847a0c37SPatrick Williams## has already been created. 133847a0c37SPatrick Williams## interfaces - list of interface paths which a YAML has been found and 134847a0c37SPatrick Williams## which YAML types (interface, errors, etc.). 135847a0c37SPatrick Williamsdeclare -A meson_paths 136847a0c37SPatrick Williamsdeclare -A interfaces 137847a0c37SPatrick Williams 138847a0c37SPatrick Williams## Ensure the meson.build files to a path have been created. 139847a0c37SPatrick Williams## $1 - The path requiring to be created. 140847a0c37SPatrick Williamsfunction meson_create_path { 141847a0c37SPatrick Williams 142847a0c37SPatrick Williams meson_path="$outputdir" 143847a0c37SPatrick Williams prev_meson_path="" 144847a0c37SPatrick Williams 145847a0c37SPatrick Williams # Split the path into segments. 146847a0c37SPatrick Williams for part in $(echo "$1" | tr '/' '\n'); 147847a0c37SPatrick Williams do 148847a0c37SPatrick Williams prev_meson_path="$meson_path" 149847a0c37SPatrick Williams meson_path="$meson_path/$part" 150847a0c37SPatrick Williams 151847a0c37SPatrick Williams # Create the meson.build for this segment if it doesn't already exist. 152847a0c37SPatrick Williams if [ "x" == "x${meson_paths[$meson_path]}" ]; 153847a0c37SPatrick Williams then 154847a0c37SPatrick Williams meson_paths["$meson_path"]="1" 155847a0c37SPatrick Williams meson_empty_file "$meson_path" 156847a0c37SPatrick Williams 157847a0c37SPatrick Williams # Add the 'subdir' link into the parent's meson.build. 158847a0c37SPatrick Williams # We need to skip adding the links into the 'root' meson.build 159847a0c37SPatrick Williams # because most repositories want to selectively add TLDs based 160847a0c37SPatrick Williams # on config flags. Let them figure out their own logic for that. 161847a0c37SPatrick Williams if [ "x$outputdir" != "x$prev_meson_path" ]; 162847a0c37SPatrick Williams then 163847a0c37SPatrick Williams echo "subdir('$part')" >> "$prev_meson_path/meson.build" 164847a0c37SPatrick Williams fi 165847a0c37SPatrick Williams fi 166847a0c37SPatrick Williams done 167847a0c37SPatrick Williams} 168847a0c37SPatrick Williams 169847a0c37SPatrick Williams## Generate the meson target for the source files (.cpp/.hpp) from a YAML 170847a0c37SPatrick Williams## interface. 171847a0c37SPatrick Williams## 172847a0c37SPatrick Williams## $1 - The interface to generate a target for. 173847a0c37SPatrick Williamsfunction meson_cpp_target { 174847a0c37SPatrick Williams 175847a0c37SPatrick Williams # Determine the source and output files based on the YAMLs present. 176847a0c37SPatrick Williams sources="" 177847a0c37SPatrick Williams outputs="" 178847a0c37SPatrick Williams for s in ${interfaces[$1]}; 179847a0c37SPatrick Williams do 180847a0c37SPatrick Williams sources="${sources}meson.source_root() / '$1.$s', " 181847a0c37SPatrick Williams 182847a0c37SPatrick Williams case "$s" in 183847a0c37SPatrick Williams errors.yaml) 184847a0c37SPatrick Williams outputs="${outputs}'error.cpp', 'error.hpp', " 185847a0c37SPatrick Williams ;; 186847a0c37SPatrick Williams 187847a0c37SPatrick Williams interface.yaml) 188847a0c37SPatrick Williams outputs="${outputs}'server.cpp', 'server.hpp', " 189847a0c37SPatrick Williams outputs="${outputs}'client.hpp', " 190847a0c37SPatrick Williams ;; 191847a0c37SPatrick Williams esac 192847a0c37SPatrick Williams done 193847a0c37SPatrick Williams 194847a0c37SPatrick Williams # Create the target to generate the 'outputs'. 195847a0c37SPatrick Williams cat >> "$outputdir/$1/meson.build" \ 196847a0c37SPatrick Williams<<EOF 197847a0c37SPatrick Williamsgenerated_sources += custom_target( 198847a0c37SPatrick Williams '$1__cpp'.underscorify(), 199847a0c37SPatrick Williams input: [ $sources ], 200847a0c37SPatrick Williams output: [ $outputs ], 201847a0c37SPatrick Williams command: [ 202847a0c37SPatrick Williams sdbuspp_gen_meson_prog, '--command', 'cpp', 203847a0c37SPatrick Williams '--output', meson.current_build_dir(), 204847a0c37SPatrick Williams '--tool', sdbusplusplus_prog, 205847a0c37SPatrick Williams '--directory', meson.source_root(), 206847a0c37SPatrick Williams '$1', 207847a0c37SPatrick Williams ], 208847a0c37SPatrick Williams) 209847a0c37SPatrick Williams 210847a0c37SPatrick WilliamsEOF 211847a0c37SPatrick Williams} 212847a0c37SPatrick Williams 213847a0c37SPatrick Williams## Generate the meson target for the markdown files from a YAML interface. 214847a0c37SPatrick Williams## $1 - The interface to generate a target for. 215847a0c37SPatrick Williamsfunction meson_md_target { 216847a0c37SPatrick Williams 217847a0c37SPatrick Williams # Determine the source files based on the YAMLs present. 218847a0c37SPatrick Williams sources="" 219847a0c37SPatrick Williams for s in ${interfaces[$1]}; 220847a0c37SPatrick Williams do 221847a0c37SPatrick Williams sources="${sources}meson.source_root() / '$1.$s', " 222847a0c37SPatrick Williams done 223847a0c37SPatrick Williams 224847a0c37SPatrick Williams # Create the target to generate the interface.md file. 225847a0c37SPatrick Williams cat >> "$outputdir/$(dirname "$1")/meson.build" \ 226847a0c37SPatrick Williams<<EOF 227847a0c37SPatrick Williamsgenerated_others += custom_target( 228847a0c37SPatrick Williams '$1__markdown'.underscorify(), 229847a0c37SPatrick Williams input: [ $sources ], 230847a0c37SPatrick Williams output: [ '$(basename "$1").md' ], 231847a0c37SPatrick Williams command: [ 232847a0c37SPatrick Williams sdbuspp_gen_meson_prog, '--command', 'markdown', 233847a0c37SPatrick Williams '--output', meson.current_build_dir(), 234847a0c37SPatrick Williams '--tool', sdbusplusplus_prog, 235847a0c37SPatrick Williams '--directory', meson.source_root(), 236847a0c37SPatrick Williams '$1', 237847a0c37SPatrick Williams ], 238847a0c37SPatrick Williams build_by_default: true, 239847a0c37SPatrick Williams) 240847a0c37SPatrick Williams 241847a0c37SPatrick WilliamsEOF 242847a0c37SPatrick Williams} 243847a0c37SPatrick Williams 244847a0c37SPatrick Williams## Handle command=meson by generating the tree of meson.build files. 245847a0c37SPatrick Williamsfunction cmd_meson { 246847a0c37SPatrick Williams TLDs="com net org xyz" 247847a0c37SPatrick Williams yamls="" 248847a0c37SPatrick Williams 249847a0c37SPatrick Williams # Find all the YAML files in the TLD subdirectories. 250847a0c37SPatrick Williams for d in $TLDs; 251847a0c37SPatrick Williams do 252847a0c37SPatrick Williams dir="$rootdir/$d" 253847a0c37SPatrick Williams if [ ! -d "$dir" ]; 254847a0c37SPatrick Williams then 255847a0c37SPatrick Williams continue 256847a0c37SPatrick Williams fi 257847a0c37SPatrick Williams 258847a0c37SPatrick Williams yamls="\ 259847a0c37SPatrick Williams $yamls \ 260847a0c37SPatrick Williams $(find "$dir" -name '*.interface.yaml' -o -name '*.errors.yaml') \ 261847a0c37SPatrick Williams " 262847a0c37SPatrick Williams done 263847a0c37SPatrick Williams 264847a0c37SPatrick Williams # Sort YAMLs 265847a0c37SPatrick Williams yamls="$(echo "$yamls" | tr " " "\n" | sort)" 266847a0c37SPatrick Williams 267847a0c37SPatrick Williams # Assign the YAML files into the hash-table by interface name. 268847a0c37SPatrick Williams for y in $yamls; 269847a0c37SPatrick Williams do 270847a0c37SPatrick Williams rel="$(realpath "--relative-to=$rootdir" "$y")" 271847a0c37SPatrick Williams dir="$(dirname "$rel")" 272847a0c37SPatrick Williams ext="${rel#*.}" 273847a0c37SPatrick Williams base="$(basename "$rel" ".$ext")" 274847a0c37SPatrick Williams 275847a0c37SPatrick Williams interfaces["$dir/$base"]="${interfaces[$dir/$base]} $ext" 276847a0c37SPatrick Williams done 277847a0c37SPatrick Williams 278847a0c37SPatrick Williams # Create the meson.build files. 279847a0c37SPatrick Williams meson_create_root 280847a0c37SPatrick Williams sorted_ifaces="$(echo "${!interfaces[@]}" | tr " " "\n" | sort)" 281847a0c37SPatrick Williams for i in ${sorted_ifaces}; 282847a0c37SPatrick Williams do 283847a0c37SPatrick Williams meson_create_path "$i" 284847a0c37SPatrick Williams meson_cpp_target "$i" 285847a0c37SPatrick Williams meson_md_target "$i" 286847a0c37SPatrick Williams done 287847a0c37SPatrick Williams} 288847a0c37SPatrick Williams 289847a0c37SPatrick Williams## Handle command=cpp by calling sdbus++ as appropriate. 290847a0c37SPatrick Williams## $1 - interface to generate. 291847a0c37SPatrick Williams## 292847a0c37SPatrick Williams## For an interface foo/bar, the outputdir is expected to be foo/bar. 293847a0c37SPatrick Williamsfunction cmd_cpp { 294847a0c37SPatrick Williams 295847a0c37SPatrick Williams if [ "x" == "x$1" ]; 296847a0c37SPatrick Williams then 297847a0c37SPatrick Williams show_usage 298847a0c37SPatrick Williams exit 1 299847a0c37SPatrick Williams fi 300847a0c37SPatrick Williams 301847a0c37SPatrick Williams if [ ! -e "$rootdir/$1.interface.yaml" ] && \ 302847a0c37SPatrick Williams [ ! -e "$rootdir/$1.errors.yaml" ]; 303847a0c37SPatrick Williams then 304847a0c37SPatrick Williams echo "Missing YAML for $1." 305847a0c37SPatrick Williams exit 1 306847a0c37SPatrick Williams fi 307847a0c37SPatrick Williams 308847a0c37SPatrick Williams mkdir -p "$outputdir" 309847a0c37SPatrick Williams 310847a0c37SPatrick Williams sdbusppcmd="$sdbuspp -r $rootdir" 311847a0c37SPatrick Williams intf="${1//\//.}" 312847a0c37SPatrick Williams 313847a0c37SPatrick Williams if [ -e "$rootdir/$1.interface.yaml" ]; 314847a0c37SPatrick Williams then 315847a0c37SPatrick Williams $sdbusppcmd interface server-header "$intf" > "$outputdir/server.hpp" 316847a0c37SPatrick Williams $sdbusppcmd interface server-cpp "$intf" > "$outputdir/server.cpp" 317847a0c37SPatrick Williams $sdbusppcmd interface client-header "$intf" > "$outputdir/client.hpp" 318847a0c37SPatrick Williams fi 319847a0c37SPatrick Williams 320847a0c37SPatrick Williams if [ -e "$rootdir/$1.errors.yaml" ]; 321847a0c37SPatrick Williams then 322847a0c37SPatrick Williams $sdbusppcmd error exception-header "$intf" > "$outputdir/error.hpp" 323847a0c37SPatrick Williams $sdbusppcmd error exception-cpp "$intf" > "$outputdir/error.cpp" 324847a0c37SPatrick Williams fi 325847a0c37SPatrick Williams} 326847a0c37SPatrick Williams 327847a0c37SPatrick Williams## Handle command=markdown by calling sdbus++ as appropriate. 328847a0c37SPatrick Williams## $1 - interface to generate. 329847a0c37SPatrick Williams## 330847a0c37SPatrick Williams## For an interface foo/bar, the outputdir is expected to be foo. 331847a0c37SPatrick Williamsfunction cmd_markdown { 332847a0c37SPatrick Williams 333847a0c37SPatrick Williams if [ "x" == "x$1" ]; 334847a0c37SPatrick Williams then 335847a0c37SPatrick Williams show_usage 336847a0c37SPatrick Williams exit 1 337847a0c37SPatrick Williams fi 338847a0c37SPatrick Williams 339847a0c37SPatrick Williams if [ ! -e "$rootdir/$1.interface.yaml" ] && \ 340847a0c37SPatrick Williams [ ! -e "$rootdir/$1.errors.yaml" ]; 341847a0c37SPatrick Williams then 342847a0c37SPatrick Williams echo "Missing YAML for $1." 343847a0c37SPatrick Williams exit 1 344847a0c37SPatrick Williams fi 345847a0c37SPatrick Williams 346847a0c37SPatrick Williams mkdir -p "$outputdir" 347847a0c37SPatrick Williams 348847a0c37SPatrick Williams sdbusppcmd="$sdbuspp -r $rootdir" 349847a0c37SPatrick Williams intf="${1//\//.}" 350847a0c37SPatrick Williams base="$(basename "$1")" 351847a0c37SPatrick Williams 352847a0c37SPatrick Williams echo -n > "$outputdir/$base.md" 353847a0c37SPatrick Williams if [ -e "$rootdir/$1.interface.yaml" ]; 354847a0c37SPatrick Williams then 355847a0c37SPatrick Williams $sdbusppcmd interface markdown "$intf" >> "$outputdir/$base.md" 356847a0c37SPatrick Williams fi 357847a0c37SPatrick Williams 358847a0c37SPatrick Williams if [ -e "$rootdir/$1.errors.yaml" ]; 359847a0c37SPatrick Williams then 360847a0c37SPatrick Williams $sdbusppcmd error markdown "$intf" >> "$outputdir/$base.md" 361847a0c37SPatrick Williams fi 362847a0c37SPatrick Williams} 363847a0c37SPatrick Williams 364847a0c37SPatrick Williams## Handle command=version. 365847a0c37SPatrick Williamsfunction cmd_version { 366847a0c37SPatrick Williams show_version 367847a0c37SPatrick Williams} 368847a0c37SPatrick Williams 369847a0c37SPatrick Williams"cmd_$cmd" "$*" 370