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