1dnl $OpenBSD: MAKEDEV.sub,v 1.14 2005/02/07 06:14:18 david Exp $ 2dnl 3dnl Copyright (c) 2001-2004 Todd T. Fries <todd@OpenBSD.org> 4dnl 5dnl Permission to use, copy, modify, and distribute this software for any 6dnl purpose with or without fee is hereby granted, provided that the above 7dnl copyright notice and this permission notice appear in all copies. 8dnl 9dnl THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 10dnl WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 11dnl MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 12dnl ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 13dnl WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 14dnl ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 15dnl OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 16dnl 17dnl 18dnl This file is an m4 file 19dnl 20dnl Conventions: 21dnl 22dnl o First, a change of quote to make shell statements like: `command` 23dnl possible 24dnl 25changequote(`{-', `-}')dnl 26dnl 27dnl o Next, change the comment character to make shell parameter 28dnl substitution possible 29dnl 30changecom(`/*', `*/')dnl 31dnl 32dnl o version info must be stripped of $ so we can say 'generated from' below 33dnl 34dnl If we just use the version string how are we going to know what arch 35dnl 'MAKEDEV.md,v' came from? 36dnl 37dnl Thus, I have used the below to create a version string looking like 38dnl 'OpenBSD: etc.sparc/MAKEDEV.inc,v...' which works, although requires 39dnl some attention if ported to another Id string setup. 40dnl 41dnl 42dnl Initialize the stacks stored in _m4_* 43dnl 44undefine({-_m4_cvs_ver-})dnl 45pushdef({-_m4_cvs_ver-}, {-done-})dnl 46dnl 47undefine({-_m4_devs-})dnl 48pushdef({-_m4_devs-}, {-done-})dnl 49dnl 50undefine({-_m4_disks-})dnl 51undefine({-_m4_disks2-})dnl 52pushdef({-_m4_disks-}, {-done-})dnl 53pushdef({-_m4_disks2-}, {-done-})dnl 54dnl 55dnl define stack 'add to' functions, only unique names queued 56dnl 57define({-ver_q-}, {-ifelse(index($1_ver, y), 0, , 58{-pushdef({-_m4_cvs_ver-}, {-$2-})define({-$1_ver-}, {-y-})-})-})dnl ver_q 59dnl 60define({-dev_q-}, {-ifelse(index(_q_$1_dev, :), 0, 61{-errprint({-duplicated dev id: $1 at -}__file__{-:-}__line__ originally at _q_$1_dev)-}, 62{-pushdef({-_m4_devs-}, {-$1-})dnl 63define({-_q_$1_dev-}, {-:-}__file__{-:-}__line__)-})-})dnl dev_q 64dnl 65define({-disk_q-}, {-ifelse(index(_q_$1_disk, :), 0, 66{-errprint({-duplicated disk id: $1 at -}__file__{-:-}__line__ originally at _q_$1_disk)-}, {-pushdef({-_m4_disks-}, {-$1-})dnl 67pushdef({-_m4_disks2-}, {-$1-})dnl 68define({-_q_$1_disks-}, {-:-}__file__{-:-}__line__)-})-})dnl disk_q 69dnl 70dnl store a version string for 'this' file 71dnl 72dnl vers ( uniqueidstring, versionstring, subdir ) 73dnl 74dnl example1: vers(__file__, {-$OpenBSD: MAKEDEV.sub,v 1.14 2005/02/07 06:14:18 david Exp $-}) 75dnl example2: vers(__file__, {-$OpenBSD: MAKEDEV.sub,v 1.14 2005/02/07 06:14:18 david Exp $-}, etc.MACHINE) 76dnl 77dnl if subdir is defined, prepend it to the filename in the version string 78dnl 79define({-vers-}, 80{-ifelse({-$3-}, {--}, 81{-ver_q(hstcl({-$1-}), {-translit({-{-$2-}-}, {-$-}, {--})-})-}, 82{-ver_q(hstcl({-$1-}), {-_addsubdir({-{-$2-}-}, $3)-})-})-})dnl 83dnl 84dnl Version info for this file: 85dnl 86vers(__file__, {-$OpenBSD: MAKEDEV.sub,v 1.14 2005/02/07 06:14:18 david Exp $-})dnl 87dnl 88dnl 89define({-_addsubdir-}, 90{-patsubst({-$1-}, {-\$(OpenBSD:) ([^\$]*)\$-}, {-\1 $2/\2-})-})dnl 91dnl 92dnl do the 'showing' of the version info 93dnl 94define({-do_vers-}, {-COMM $1-})dnl 95dnl 96dnl show version function, to be called at the place when all versions are 97dnl queued, and it is time to show all of them 98dnl 99define({-show_vers-}, 100{-ifelse(_m4_cvs_ver, {-done-}, {--}, 101{-do_vers(_m4_cvs_ver) 102popdef({-_m4_cvs_ver-})dnl 103show_vers()dnl 104-})-})dnl 105dnl 106dnl show the routines to generate devices 107define({-show_devs-}, 108{-ifelse(_m4_devs, {-done-}, {--}, 109{-_MKDEV(_m4_devs){--}dnl 110popdef({-_m4_devs-})dnl 111show_devs()dnl 112-})-})dnl 113dnl 114dnl routines to generate disks 115define({-show_disks-}, 116{-ifelse(_m4_disks, {-done-}, {--}, 117{-ifcase(_m4_disks, _m4_disks{--}*)dnl 118popdef({-_m4_disks-})dnl 119show_disks()dnl 120-})-})dnl 121dnl 122define({-show_disks2-}, 123{-ifelse(_m4_disks2, {-done-}, {--}, 124{-CasE(_m4_disks2)dnl 125popdef({-_m4_disks2-})dnl 126show_disks2()dnl 127-})-})dnl 128dnl 129dnl 130dnl Some m4 math functions: 131dnl 132dnl Add(a, b) - displays the result of a+b 133dnl Mult(a, b) - displays the result of a*b 134dnl trunc a b - displays the string a minus b removed from the RHS 135dnl hex a - displays the hex equivalent of 0-15 136dnl unt a - s/[a-z]*([0-9]*).*/\1/ aka sd0a -> 0 137dnl 138dnl Functions: 139dnl 140dnl --> Addition 141dnl 142define({-Add-}, {-$({-(-}$1+$2{-)-})-})dnl 143dnl 144dnl --> Multiplication 145dnl 146define({-Mult-}, {-$({-(-}$1*$2{-)-})-})dnl 147dnl 148dnl 149dnl TRUNC 150dnl 151define({-expr_trunc-}, {-$1trunc() 152$1{ 153$1 case {-$-}3 in 154$1 l) {-expr-} {-$-}1 : '\(.*\)'{-$-}2 ;; 155$1 r|*) {-expr-} ${--}1 : ${--}2'\(.*\)' ;; 156$1 esac 157$1}-})dnl 158dnl 159dnl 160define({-_SHELL-}, {-sh-})dnl 161define({-_this-}, {-{-$-}T-})dnl 162dnl define({-_recurse-}, {-_SHELL _this-})dnl 163define({-_recurse-}, {-R-})dnl 164dnl 165dnl _devitem(pattern, description) 166dnl 167define({-_devitem-}, 168{-{-#-} $1 {-$2-}-})dnl 169dnl 170dnl _devtitle(description) 171dnl 172define({-_devtitle-}, {-{-#-} $1:-})dnl 173dnl 174dnl _DEV(name, [character major], [block major]) 175dnl 176define({-_DEV-}, {-$1_dev{--}dnl 177dnl 178dnl _DEV 'ifelse' .. $2 - major_$1_c 179dnl 180ifelse($2, , , {-define(major_$1_c, $2)-})dnl 181dnl 182dnl _DEV 'ifelse' .. $3 - major_$1_b 183dnl 184ifelse($3, , , {-define(major_$1_b, $3)-})dnl 185dnl 186dnl _DEV 'ifelse' .. $4 - step_$1 187dnl 188ifelse($4, , , {-define(step_$1, {-$4-})-})dnl 189dnl 190dnl Some magic here, defining a devitem also defines another 191dnl string so that later we can check if a particular devitem was 192dnl defined, and thus determine if the devices themselves are to 193dnl be built 194dnl 195define({-$1__DEV-}, {-Y-})dnl 196dnl 197dnl More magic, put device string name into a queue of script segments to 198dnl be shown later if it has been defined as a device in MAKEDEV.mi 199dnl 200ifdef({-$1_mkdev-}, {-__mkdev({-$1-})-})dnl 201dnl 202dnl 203-})dnl _DEV 204dnl 205dnl 206define({-ifdev-}, {-ifelse($1__DEV, Y, {-$2-})-})dnl 207dnl 208define({-_MKDEV-}, {-$1_mkdev-})dnl 209define({-_TITLE-}, {-$1_title-})dnl 210define({-__devitem-}, {-define($1_dev, {-_devitem($2, $3)-})-})dnl 211define({-__devtitle-}, {-define($1_title, {-_devtitle($2)-})-})dnl 212dnl 213dnl Beginning and ending of case entries, just incase we change in the 214dnl future, save chasing things down again 215dnl 216define({-_end-}, {- 217 ;; 218 219-})dnl 220define({-_beg-}, {-{-)-} 221 -})dnl 222dnl 223dnl create the script segment for making devices 224dnl $1 $2 $3 225dnl _mkdev(shortname, devpatt, action)dnl 226define({-_mkdev-}, {-define($1_mkdev, {-$2{--}_beg{--}$3{--}_end-})-})dnl 227dnl 228dnl define a major character device 229dnl $1 $2 $3 $4 230dnl _mcdev(shortname, devpatt, devbase, devmajor [, group [ owner ] ])dnl 231dnl 232define({-_mcdev-}, {-define($1_mkdev, {-{-$2-}_beg{--}M $3$U c $4 $U{--}dnl 233ifelse($6, , ifelse($5, , , {- -}$5), {- -}ifelse($5, , 600, $5){- -}$6){--}_end-})-})dnl 234dnl 235dnl $1 $2 $3 $4 $5 $6 236dnl _cdev(shortname, devpatt, devmajor, devminor[, devmod, devgrp])dnl 237define({-_cdev-}, 238{-dnl 239define($1_mkdev, {-$2{--}_beg{--}M $2 c $3 $4 $5 $6{--}_end-}){--}-})dnl 240dnl 241dnl 242define({-__mkdev-}, {-dev_q($1)-})dnl 243dnl 244dnl for showing disks 245dnl 246define({-CasE-}, 247{-ifdev({-$1-}, 248{- $1*) dodisk $1 $U major_$1_b major_$1_c $U 0{--}ifstep($1);; 249-})-})dnl 250dnl 251dnl 252define({-ifcase-}, {-dnl 253ifelse(C_ase, Y, ifdev({-$1-}, {-|$2-}), 254{-ifdev({-$1-}, {-$2define({-C_ase-}, Y)-})-})-})dnl 255dnl 256dnl 257dnl device list .. list devices 'iff' they are defined 258dnl 259dnl input: 260dnl 261dnl _dl({-usb-}, {-usb0 usb1-}, {-urio-}, {-urio-}, ...) 262dnl 263dnl output: 264dnl 265dnl {-<tab>_recurse usb0 usb1 urio 266dnl <tab>_recurse uhid0 uhid2 uhid3-} 267dnl 268dnl wrap if more than 60 chars wide 269dnl 270dnl .. wrap it all up in an 'ifelse({-$1-}, , {- ... -})' for neatness ?? 271dnl 272define({-_dl-}, {-dnl 273ifdef({-_dt-}, , {-define({-_dt-})-})dnl 274ifdef({-_do-}, , {-_dt{--}_recurse{--}define({-_do-}, 0)dnl 275define({-_dt-}, {- -})-})dnl 276ifdef({-$1__DEV-}, 277{-define({-_di-}, {-$2-})-}, 278{-define({-_di-})-})dnl 279ifelse(eval(len(_di)+_do<60), 1, 280{-ifelse(eval(len(_di)>0), 1, 281{- _di{--}define({-_do-}, eval(1+_do+len(_di)))-})-}, 282{- 283_dt{--}_recurse _di{--}dnl 284define({-_do-}, len(_di))-})dnl 285ifelse({-$3-}, {--}, 286{-undefine({-_dt-}, {-_do-})-}, dnl <--- The END 287{-_dl(shift(shift($@)))-})-})dnl 288dnl 289dnl 290define({-_show_target-}, {-dnl 291ifdef({-$1__DEV-}, {-disp_dev({-$2-})-})dnl 292ifelse({-$3-}, {--}, 293{-_disp_dev_end()-}, dnl <--- The END 294{-_show_target(shift(shift($@)))-})-})dnl 295dnl 296define({-disp_dev-}, {-dnl 297ifdef({-_disp_dev_tab-}, , {-define({-_disp_dev_tab-})-})dnl 298ifdef({-_disp_dev_len-}, , {-dnl 299define({-_disp_dev_len-}, 0)dnl 300_disp_dev_tab{--}_recurse{--}dnl 301define({-_disp_dev_tab-}, {- -})-})dnl 302ifelse(eval(len($1)+_disp_dev_len<60), 1, 303{- $1{--}define({-_disp_dev_len-}, eval(1+_disp_dev_len+len($1)))-}, {- 304_disp_dev_tab{--}_recurse $1{--}dnl 305define({-_disp_dev_len-}, len($1))-})dnl 306-})dnl 307define({-_disp_dev_end-}, {-undefine({-_disp_dev_tab-}, {-_disp_dev_len-})-})dnl 308dnl 309dnl A word about the above: 310dnl 311dnl _dt -> 'tab' .. at first, defined to nothing, as the tab is already there 312dnl then define it to a tab every time through 313dnl undefine it at the end 314dnl 315dnl _do -> 'old' count .. stores the length of the old string already displayed 316dnl it is initialized to 0, added to the length plus 1 of '_di' each 317dnl iteration the line is less than 60 chars long 318dnl undefined at the end 319dnl _di -> 'iteration' string .. the string used in this iteration, is empty if 320dnl the device does not exist 321dnl 322dnl 323dnl ifstep(devstr) 324dnl .. if stepping is defined for the particular device, emit ' step', else 325dnl nothing 326define({-ifstep-}, {-ifdef({-step_$1-}, {- -}step_$1{--})-})dnl 327dnl 328dnl 329define({-target-}, {-twrget({-$1-}, {-$2-}, {-$2-}, shift(shift($@)))-})dnl 330dnl 331dnl twrget(target, devname, prefix, str1, str2, str3) 332dnl $1 $2 $3 $4 $5 $6 333dnl 334define({-twrget-}, {-dnl 335dnl 336ifdef({-$1_target-}, , {-pushdef({-$1_target-}, {-done-})-})dnl 337dnl 338ifelse({-$4-}, , , {-dnl 339ifelse({-$4-}, {-_done-}, , {-dnl 340ifelse({-$5-}, , , {-dnl 341dnl errprint({-recurse: $1, $2, $3, $4, $5, $6, ...-})dnl 342twrget({-$1-}, {-$2-}, {-$3-}, shift(shift(shift(shift($@)))))dnl 343-})-})-})dnl 344dnl 345ifelse({-$4-}, {-_done-}, , {-dnl 346dnl errprint({-recurse: $1_$2_dev, $3$4, $3$4, _done-})dnl 347twrget({-$1_$2_dev-}, {-$3$4-}, {-$3$4-}, {-_done-})dnl 348-})dnl 349dnl 350ifdef({-$1$2target-}, , {-dnl 351pushdef({-$1_target-}, {-$2-})define({-$1$2target-})dnl 352-})dnl 353dnl 354-})dnl 355dnl 356dnl 357define({-show_target-}, {-dnl 358ifelse($1_target, {-done-}, {-_disp_dev_end()-}, 359{-dnl $1_target: 360show_dev($1, -}$1_target{-)dnl 361popdef({-$1_target-})dnl 362show_target({-$1-})dnl 363-})-})dnl 364dnl 365define({-show_dev-}, {-dnl 366ifdef({-$2__DEV-}, {-dnl 367ifelse($1_$2_dev_target, {-done-}, , {-dnl 368disp_dev({-$1_$2_dev_target-})dnl 369popdef({-$1_$2_dev_target-})dnl 370show_dev({-$1-}, {-$2-})-})dnl 371-})dnl 372-})dnl 373dnl 374