1*847a0c37SPatrick Williams#!/usr/bin/env bash 2*847a0c37SPatrick Williams 3*847a0c37SPatrick Williamsset -e 4*847a0c37SPatrick Williams 5*847a0c37SPatrick Williamsfunction show_usage { 6*847a0c37SPatrick Williams cat \ 7*847a0c37SPatrick Williams<<EOF 8*847a0c37SPatrick WilliamsUsage: $(basename "$0") [options] <command-args>* 9*847a0c37SPatrick Williams 10*847a0c37SPatrick WilliamsGenerate meson.build files from a directory tree containing YAML files and 11*847a0c37SPatrick Williamsfacilitate building the sdbus++ sources. 12*847a0c37SPatrick Williams 13*847a0c37SPatrick WilliamsOptions: 14*847a0c37SPatrick Williams --help - Display this message 15*847a0c37SPatrick Williams --command <cmd> - Command mode to execute (default 'meson'). 16*847a0c37SPatrick Williams --directory <path> - Root directory of the YAML source (default '.'). 17*847a0c37SPatrick Williams --output <path> - Root directory of the output (default '.'). 18*847a0c37SPatrick Williams --tool <path> - Path to the processing tool (default 'sdbus++'). 19*847a0c37SPatrick Williams --version - Display this tool's version string. 20*847a0c37SPatrick Williams 21*847a0c37SPatrick WilliamsCommands: 22*847a0c37SPatrick Williams meson - Generate a tree of meson.build files corresponding 23*847a0c37SPatrick Williams to the source YAML files. 24*847a0c37SPatrick Williams cpp <intf> - Generate the source files from a YAML interface. 25*847a0c37SPatrick Williams markdown <intf> - Generate the markdown files from a YAML interface. 26*847a0c37SPatrick Williams version - Display this tool's version string. 27*847a0c37SPatrick Williams 28*847a0c37SPatrick WilliamsEOF 29*847a0c37SPatrick Williams} 30*847a0c37SPatrick Williams 31*847a0c37SPatrick Williams## The version is somewhat arbitrary but is used to create a warning message 32*847a0c37SPatrick Williams## if a repository contains old copies of the generated meson.build files and 33*847a0c37SPatrick Williams## needs an update. We should increment the version number whenever the 34*847a0c37SPatrick Williams## resulting meson.build would change. 35*847a0c37SPatrick Williamstool_version="sdbus++-gen-meson version 1" 36*847a0c37SPatrick Williamsfunction show_version { 37*847a0c37SPatrick Williams echo "$tool_version" 38*847a0c37SPatrick Williams} 39*847a0c37SPatrick Williams 40*847a0c37SPatrick Williams# Set up defaults. 41*847a0c37SPatrick Williamssdbuspp="sdbus++" 42*847a0c37SPatrick Williamsoutputdir="." 43*847a0c37SPatrick Williamscmd="meson" 44*847a0c37SPatrick Williamsrootdir="." 45*847a0c37SPatrick Williams 46*847a0c37SPatrick Williams# Parse options. 47*847a0c37SPatrick Williamsoptions="$(getopt -o hc:d:o:t:v --long help,command:,directory:,output:,tool:,version -- "$@")" 48*847a0c37SPatrick Williamseval set -- "$options" 49*847a0c37SPatrick Williams 50*847a0c37SPatrick Williamswhile true; 51*847a0c37SPatrick Williamsdo 52*847a0c37SPatrick Williams case "$1" in 53*847a0c37SPatrick Williams -h | --help) 54*847a0c37SPatrick Williams show_usage 55*847a0c37SPatrick Williams exit 56*847a0c37SPatrick Williams ;; 57*847a0c37SPatrick Williams 58*847a0c37SPatrick Williams -c | --command) 59*847a0c37SPatrick Williams shift 60*847a0c37SPatrick Williams cmd="$1" 61*847a0c37SPatrick Williams shift 62*847a0c37SPatrick Williams ;; 63*847a0c37SPatrick Williams 64*847a0c37SPatrick Williams -d | --directory) 65*847a0c37SPatrick Williams shift 66*847a0c37SPatrick Williams rootdir="$1" 67*847a0c37SPatrick Williams shift 68*847a0c37SPatrick Williams ;; 69*847a0c37SPatrick Williams 70*847a0c37SPatrick Williams -o | --output) 71*847a0c37SPatrick Williams shift 72*847a0c37SPatrick Williams outputdir="$1" 73*847a0c37SPatrick Williams shift 74*847a0c37SPatrick Williams ;; 75*847a0c37SPatrick Williams 76*847a0c37SPatrick Williams -t | --tool) 77*847a0c37SPatrick Williams shift 78*847a0c37SPatrick Williams sdbuspp="$1" 79*847a0c37SPatrick Williams shift 80*847a0c37SPatrick Williams ;; 81*847a0c37SPatrick Williams 82*847a0c37SPatrick Williams -v | --version) 83*847a0c37SPatrick Williams show_version 84*847a0c37SPatrick Williams exit 85*847a0c37SPatrick Williams ;; 86*847a0c37SPatrick Williams 87*847a0c37SPatrick Williams --) 88*847a0c37SPatrick Williams shift 89*847a0c37SPatrick Williams break 90*847a0c37SPatrick Williams ;; 91*847a0c37SPatrick Williams esac 92*847a0c37SPatrick Williamsdone 93*847a0c37SPatrick Williams 94*847a0c37SPatrick Williams## Create an initially empty meson.build file. 95*847a0c37SPatrick Williams## $1 - path to create meson.build at. 96*847a0c37SPatrick Williamsfunction meson_empty_file { 97*847a0c37SPatrick Williams mkdir -p "$1" 98*847a0c37SPatrick Williams echo "# Generated file; do not modify." > "$1/meson.build" 99*847a0c37SPatrick Williams} 100*847a0c37SPatrick Williams 101*847a0c37SPatrick Williams## Create the root-level meson.build 102*847a0c37SPatrick Williams## 103*847a0c37SPatrick Williams## Inserts rules to run the available version of this tool to ensure the 104*847a0c37SPatrick Williams## version has not changed. 105*847a0c37SPatrick Williamsfunction meson_create_root { 106*847a0c37SPatrick Williams meson_empty_file "$outputdir" 107*847a0c37SPatrick Williams 108*847a0c37SPatrick Williams cat >> "$outputdir/meson.build" \ 109*847a0c37SPatrick Williams<<EOF 110*847a0c37SPatrick Williamssdbuspp_gen_meson_ver = run_command( 111*847a0c37SPatrick Williams sdbuspp_gen_meson_prog, 112*847a0c37SPatrick Williams '--version', 113*847a0c37SPatrick Williams).stdout().strip().split('\n')[0] 114*847a0c37SPatrick Williams 115*847a0c37SPatrick Williamsif sdbuspp_gen_meson_ver != '$tool_version' 116*847a0c37SPatrick Williams warning('Generated meson files from wrong version of sdbus++-gen-meson.') 117*847a0c37SPatrick Williams warning( 118*847a0c37SPatrick Williams 'Expected "$tool_version", got:', 119*847a0c37SPatrick Williams sdbuspp_gen_meson_ver 120*847a0c37SPatrick Williams ) 121*847a0c37SPatrick Williamsendif 122*847a0c37SPatrick Williams 123*847a0c37SPatrick WilliamsEOF 124*847a0c37SPatrick Williams} 125*847a0c37SPatrick Williams 126*847a0c37SPatrick Williams## hash-tables to store: 127*847a0c37SPatrick Williams## meson_paths - list of subdirectory paths for which an empty meson.build 128*847a0c37SPatrick Williams## has already been created. 129*847a0c37SPatrick Williams## interfaces - list of interface paths which a YAML has been found and 130*847a0c37SPatrick Williams## which YAML types (interface, errors, etc.). 131*847a0c37SPatrick Williamsdeclare -A meson_paths 132*847a0c37SPatrick Williamsdeclare -A interfaces 133*847a0c37SPatrick Williams 134*847a0c37SPatrick Williams## Ensure the meson.build files to a path have been created. 135*847a0c37SPatrick Williams## $1 - The path requiring to be created. 136*847a0c37SPatrick Williamsfunction meson_create_path { 137*847a0c37SPatrick Williams 138*847a0c37SPatrick Williams meson_path="$outputdir" 139*847a0c37SPatrick Williams prev_meson_path="" 140*847a0c37SPatrick Williams 141*847a0c37SPatrick Williams # Split the path into segments. 142*847a0c37SPatrick Williams for part in $(echo "$1" | tr '/' '\n'); 143*847a0c37SPatrick Williams do 144*847a0c37SPatrick Williams prev_meson_path="$meson_path" 145*847a0c37SPatrick Williams meson_path="$meson_path/$part" 146*847a0c37SPatrick Williams 147*847a0c37SPatrick Williams # Create the meson.build for this segment if it doesn't already exist. 148*847a0c37SPatrick Williams if [ "x" == "x${meson_paths[$meson_path]}" ]; 149*847a0c37SPatrick Williams then 150*847a0c37SPatrick Williams meson_paths["$meson_path"]="1" 151*847a0c37SPatrick Williams meson_empty_file "$meson_path" 152*847a0c37SPatrick Williams 153*847a0c37SPatrick Williams # Add the 'subdir' link into the parent's meson.build. 154*847a0c37SPatrick Williams # We need to skip adding the links into the 'root' meson.build 155*847a0c37SPatrick Williams # because most repositories want to selectively add TLDs based 156*847a0c37SPatrick Williams # on config flags. Let them figure out their own logic for that. 157*847a0c37SPatrick Williams if [ "x$outputdir" != "x$prev_meson_path" ]; 158*847a0c37SPatrick Williams then 159*847a0c37SPatrick Williams echo "subdir('$part')" >> "$prev_meson_path/meson.build" 160*847a0c37SPatrick Williams fi 161*847a0c37SPatrick Williams fi 162*847a0c37SPatrick Williams done 163*847a0c37SPatrick Williams} 164*847a0c37SPatrick Williams 165*847a0c37SPatrick Williams## Generate the meson target for the source files (.cpp/.hpp) from a YAML 166*847a0c37SPatrick Williams## interface. 167*847a0c37SPatrick Williams## 168*847a0c37SPatrick Williams## $1 - The interface to generate a target for. 169*847a0c37SPatrick Williamsfunction meson_cpp_target { 170*847a0c37SPatrick Williams 171*847a0c37SPatrick Williams # Determine the source and output files based on the YAMLs present. 172*847a0c37SPatrick Williams sources="" 173*847a0c37SPatrick Williams outputs="" 174*847a0c37SPatrick Williams for s in ${interfaces[$1]}; 175*847a0c37SPatrick Williams do 176*847a0c37SPatrick Williams sources="${sources}meson.source_root() / '$1.$s', " 177*847a0c37SPatrick Williams 178*847a0c37SPatrick Williams case "$s" in 179*847a0c37SPatrick Williams errors.yaml) 180*847a0c37SPatrick Williams outputs="${outputs}'error.cpp', 'error.hpp', " 181*847a0c37SPatrick Williams ;; 182*847a0c37SPatrick Williams 183*847a0c37SPatrick Williams interface.yaml) 184*847a0c37SPatrick Williams outputs="${outputs}'server.cpp', 'server.hpp', " 185*847a0c37SPatrick Williams outputs="${outputs}'client.hpp', " 186*847a0c37SPatrick Williams ;; 187*847a0c37SPatrick Williams esac 188*847a0c37SPatrick Williams done 189*847a0c37SPatrick Williams 190*847a0c37SPatrick Williams # Create the target to generate the 'outputs'. 191*847a0c37SPatrick Williams cat >> "$outputdir/$1/meson.build" \ 192*847a0c37SPatrick Williams<<EOF 193*847a0c37SPatrick Williamsgenerated_sources += custom_target( 194*847a0c37SPatrick Williams '$1__cpp'.underscorify(), 195*847a0c37SPatrick Williams input: [ $sources ], 196*847a0c37SPatrick Williams output: [ $outputs ], 197*847a0c37SPatrick Williams command: [ 198*847a0c37SPatrick Williams sdbuspp_gen_meson_prog, '--command', 'cpp', 199*847a0c37SPatrick Williams '--output', meson.current_build_dir(), 200*847a0c37SPatrick Williams '--tool', sdbusplusplus_prog, 201*847a0c37SPatrick Williams '--directory', meson.source_root(), 202*847a0c37SPatrick Williams '$1', 203*847a0c37SPatrick Williams ], 204*847a0c37SPatrick Williams) 205*847a0c37SPatrick Williams 206*847a0c37SPatrick WilliamsEOF 207*847a0c37SPatrick Williams} 208*847a0c37SPatrick Williams 209*847a0c37SPatrick Williams## Generate the meson target for the markdown files from a YAML interface. 210*847a0c37SPatrick Williams## $1 - The interface to generate a target for. 211*847a0c37SPatrick Williamsfunction meson_md_target { 212*847a0c37SPatrick Williams 213*847a0c37SPatrick Williams # Determine the source files based on the YAMLs present. 214*847a0c37SPatrick Williams sources="" 215*847a0c37SPatrick Williams for s in ${interfaces[$1]}; 216*847a0c37SPatrick Williams do 217*847a0c37SPatrick Williams sources="${sources}meson.source_root() / '$1.$s', " 218*847a0c37SPatrick Williams done 219*847a0c37SPatrick Williams 220*847a0c37SPatrick Williams # Create the target to generate the interface.md file. 221*847a0c37SPatrick Williams cat >> "$outputdir/$(dirname "$1")/meson.build" \ 222*847a0c37SPatrick Williams<<EOF 223*847a0c37SPatrick Williamsgenerated_others += custom_target( 224*847a0c37SPatrick Williams '$1__markdown'.underscorify(), 225*847a0c37SPatrick Williams input: [ $sources ], 226*847a0c37SPatrick Williams output: [ '$(basename "$1").md' ], 227*847a0c37SPatrick Williams command: [ 228*847a0c37SPatrick Williams sdbuspp_gen_meson_prog, '--command', 'markdown', 229*847a0c37SPatrick Williams '--output', meson.current_build_dir(), 230*847a0c37SPatrick Williams '--tool', sdbusplusplus_prog, 231*847a0c37SPatrick Williams '--directory', meson.source_root(), 232*847a0c37SPatrick Williams '$1', 233*847a0c37SPatrick Williams ], 234*847a0c37SPatrick Williams build_by_default: true, 235*847a0c37SPatrick Williams) 236*847a0c37SPatrick Williams 237*847a0c37SPatrick WilliamsEOF 238*847a0c37SPatrick Williams} 239*847a0c37SPatrick Williams 240*847a0c37SPatrick Williams## Handle command=meson by generating the tree of meson.build files. 241*847a0c37SPatrick Williamsfunction cmd_meson { 242*847a0c37SPatrick Williams TLDs="com net org xyz" 243*847a0c37SPatrick Williams yamls="" 244*847a0c37SPatrick Williams 245*847a0c37SPatrick Williams # Find all the YAML files in the TLD subdirectories. 246*847a0c37SPatrick Williams for d in $TLDs; 247*847a0c37SPatrick Williams do 248*847a0c37SPatrick Williams dir="$rootdir/$d" 249*847a0c37SPatrick Williams if [ ! -d "$dir" ]; 250*847a0c37SPatrick Williams then 251*847a0c37SPatrick Williams continue 252*847a0c37SPatrick Williams fi 253*847a0c37SPatrick Williams 254*847a0c37SPatrick Williams yamls="\ 255*847a0c37SPatrick Williams $yamls \ 256*847a0c37SPatrick Williams $(find "$dir" -name '*.interface.yaml' -o -name '*.errors.yaml') \ 257*847a0c37SPatrick Williams " 258*847a0c37SPatrick Williams done 259*847a0c37SPatrick Williams 260*847a0c37SPatrick Williams # Sort YAMLs 261*847a0c37SPatrick Williams yamls="$(echo "$yamls" | tr " " "\n" | sort)" 262*847a0c37SPatrick Williams 263*847a0c37SPatrick Williams # Assign the YAML files into the hash-table by interface name. 264*847a0c37SPatrick Williams for y in $yamls; 265*847a0c37SPatrick Williams do 266*847a0c37SPatrick Williams rel="$(realpath "--relative-to=$rootdir" "$y")" 267*847a0c37SPatrick Williams dir="$(dirname "$rel")" 268*847a0c37SPatrick Williams ext="${rel#*.}" 269*847a0c37SPatrick Williams base="$(basename "$rel" ".$ext")" 270*847a0c37SPatrick Williams 271*847a0c37SPatrick Williams interfaces["$dir/$base"]="${interfaces[$dir/$base]} $ext" 272*847a0c37SPatrick Williams done 273*847a0c37SPatrick Williams 274*847a0c37SPatrick Williams # Create the meson.build files. 275*847a0c37SPatrick Williams meson_create_root 276*847a0c37SPatrick Williams sorted_ifaces="$(echo "${!interfaces[@]}" | tr " " "\n" | sort)" 277*847a0c37SPatrick Williams for i in ${sorted_ifaces}; 278*847a0c37SPatrick Williams do 279*847a0c37SPatrick Williams meson_create_path "$i" 280*847a0c37SPatrick Williams meson_cpp_target "$i" 281*847a0c37SPatrick Williams meson_md_target "$i" 282*847a0c37SPatrick Williams done 283*847a0c37SPatrick Williams} 284*847a0c37SPatrick Williams 285*847a0c37SPatrick Williams## Handle command=cpp by calling sdbus++ as appropriate. 286*847a0c37SPatrick Williams## $1 - interface to generate. 287*847a0c37SPatrick Williams## 288*847a0c37SPatrick Williams## For an interface foo/bar, the outputdir is expected to be foo/bar. 289*847a0c37SPatrick Williamsfunction cmd_cpp { 290*847a0c37SPatrick Williams 291*847a0c37SPatrick Williams if [ "x" == "x$1" ]; 292*847a0c37SPatrick Williams then 293*847a0c37SPatrick Williams show_usage 294*847a0c37SPatrick Williams exit 1 295*847a0c37SPatrick Williams fi 296*847a0c37SPatrick Williams 297*847a0c37SPatrick Williams if [ ! -e "$rootdir/$1.interface.yaml" ] && \ 298*847a0c37SPatrick Williams [ ! -e "$rootdir/$1.errors.yaml" ]; 299*847a0c37SPatrick Williams then 300*847a0c37SPatrick Williams echo "Missing YAML for $1." 301*847a0c37SPatrick Williams exit 1 302*847a0c37SPatrick Williams fi 303*847a0c37SPatrick Williams 304*847a0c37SPatrick Williams mkdir -p "$outputdir" 305*847a0c37SPatrick Williams 306*847a0c37SPatrick Williams sdbusppcmd="$sdbuspp -r $rootdir" 307*847a0c37SPatrick Williams intf="${1//\//.}" 308*847a0c37SPatrick Williams 309*847a0c37SPatrick Williams if [ -e "$rootdir/$1.interface.yaml" ]; 310*847a0c37SPatrick Williams then 311*847a0c37SPatrick Williams $sdbusppcmd interface server-header "$intf" > "$outputdir/server.hpp" 312*847a0c37SPatrick Williams $sdbusppcmd interface server-cpp "$intf" > "$outputdir/server.cpp" 313*847a0c37SPatrick Williams $sdbusppcmd interface client-header "$intf" > "$outputdir/client.hpp" 314*847a0c37SPatrick Williams fi 315*847a0c37SPatrick Williams 316*847a0c37SPatrick Williams if [ -e "$rootdir/$1.errors.yaml" ]; 317*847a0c37SPatrick Williams then 318*847a0c37SPatrick Williams $sdbusppcmd error exception-header "$intf" > "$outputdir/error.hpp" 319*847a0c37SPatrick Williams $sdbusppcmd error exception-cpp "$intf" > "$outputdir/error.cpp" 320*847a0c37SPatrick Williams fi 321*847a0c37SPatrick Williams} 322*847a0c37SPatrick Williams 323*847a0c37SPatrick Williams## Handle command=markdown by calling sdbus++ as appropriate. 324*847a0c37SPatrick Williams## $1 - interface to generate. 325*847a0c37SPatrick Williams## 326*847a0c37SPatrick Williams## For an interface foo/bar, the outputdir is expected to be foo. 327*847a0c37SPatrick Williamsfunction cmd_markdown { 328*847a0c37SPatrick Williams 329*847a0c37SPatrick Williams if [ "x" == "x$1" ]; 330*847a0c37SPatrick Williams then 331*847a0c37SPatrick Williams show_usage 332*847a0c37SPatrick Williams exit 1 333*847a0c37SPatrick Williams fi 334*847a0c37SPatrick Williams 335*847a0c37SPatrick Williams if [ ! -e "$rootdir/$1.interface.yaml" ] && \ 336*847a0c37SPatrick Williams [ ! -e "$rootdir/$1.errors.yaml" ]; 337*847a0c37SPatrick Williams then 338*847a0c37SPatrick Williams echo "Missing YAML for $1." 339*847a0c37SPatrick Williams exit 1 340*847a0c37SPatrick Williams fi 341*847a0c37SPatrick Williams 342*847a0c37SPatrick Williams mkdir -p "$outputdir" 343*847a0c37SPatrick Williams 344*847a0c37SPatrick Williams sdbusppcmd="$sdbuspp -r $rootdir" 345*847a0c37SPatrick Williams intf="${1//\//.}" 346*847a0c37SPatrick Williams base="$(basename "$1")" 347*847a0c37SPatrick Williams 348*847a0c37SPatrick Williams echo -n > "$outputdir/$base.md" 349*847a0c37SPatrick Williams if [ -e "$rootdir/$1.interface.yaml" ]; 350*847a0c37SPatrick Williams then 351*847a0c37SPatrick Williams $sdbusppcmd interface markdown "$intf" >> "$outputdir/$base.md" 352*847a0c37SPatrick Williams fi 353*847a0c37SPatrick Williams 354*847a0c37SPatrick Williams if [ -e "$rootdir/$1.errors.yaml" ]; 355*847a0c37SPatrick Williams then 356*847a0c37SPatrick Williams $sdbusppcmd error markdown "$intf" >> "$outputdir/$base.md" 357*847a0c37SPatrick Williams fi 358*847a0c37SPatrick Williams} 359*847a0c37SPatrick Williams 360*847a0c37SPatrick Williams## Handle command=version. 361*847a0c37SPatrick Williamsfunction cmd_version { 362*847a0c37SPatrick Williams show_version 363*847a0c37SPatrick Williams} 364*847a0c37SPatrick Williams 365*847a0c37SPatrick Williams"cmd_$cmd" "$*" 366