1/*
2 * {automake|configure} => {nmake|iffe} conversion support
3 *
4 * The first command line target overrides the default original source
5 * directory name $(MAKEFILE:D). The hard work is in the makefile using
6 * these assertions, since it must (manually) provide the nmake makefiles
7 * and config equivalent iffe scripts. The conversion makefile is typically
8 * named lib/package/PACKAGE.cvt in an ast package $PACKAGEROOT directory,
9 * and the conversion is run from the $PACKAGEROOT directory, e.g.:
10 *
11 *	nmake -I lib/package -f PACKAGE-VERSION/PACKAGE.cvt
12 *
13 * The conversion requires the ast nmake, pax and tw commands.
14 *
15 * After the conversion you will be liberated from ./configure, *.in,
16 * *.am, automake, autom4te, libtool, make depend, and makefile
17 * recursion ordering. You can build from $PACKAGEROOT using the ast
18 * package(1) (which sets up the { HOSTTYPE PATH VPATH } environment):
19 *
20 *	package make
21 *
22 * or cd into any arch/$HOSTTYPE/src subdirectory and rebuild that portion
23 * of the hierarchy with the ast nmake(1) (after setting PATH and VPATH):
24 *
25 *	nmake
26 *
27 * The conversion assertions are:
28 *
29 *	package :CONVERT: file ...
30 *
31 *	    files in the original source directory are copied
32 *	    and converted into the ./src and ./lib subdirectories
33 *	    the default original source directory is ./original
34 *
35 *		package	package name
36 *		file	original source file that must exist
37 *
38 *	:OMIT: pattern
39 *
40 *	    files matching pattern are not copied into the converted
41 *	    directory
42 *
43 *		pattern	ksh pattern of files to omit
44 *
45 *	:COPY: from to [ file ... ]
46 *
47 *	    files in the from directory are copied to the to directory
48 *	    the action may contain :MOVE: exceptions to the copy
49 *
50 *		from	original directory subdirectory
51 *			  . names the original directory
52 *			 .. names the
53 *		to	converted subdirectory
54 *			  libNAME => src/lib/libNAME
55 *			     NAME => src/cmd/NAME
56 *		file	files or files in subdirectories to be copied;
57 *			explicit files are copied to the to directory;
58 *			if no files are specified then the from hierarchy
59 *			is recursively copied to the converted directory
60 *
61 *	:MOVE: to file ...
62 *
63 *	    :COPY: assertion exceptions placed in the assertion's action
64 *
65 *		to	files or subdirectory files are copied to this directory
66 *		file	file or files in subdirectories to be copied
67 *
68 *	:FILE: to file <<!
69 *	contents
70 *	!
71 *
72 *	    the :FILE: action is copied to the named file in the to directory
73 *	    the :FILE: action is usually specified using the here syntax to
74 *	    avoid make comment, quote and variable expansion
75 *
76 *	:EDIT: to file ... | - pattern <<!
77 *	edit script
78 *	!
79 *
80 *	    the :EDIT: action is an ed(1) script applied to each file in the
81 *	    to directory after it has been copied from the original source
82 *	    directory; if to is - then the :EDIT: action is a sed(1) script
83 *	    that is applied to all files matching the file pattern during the
84 *	    copy from the original source directory; a file may be subject to
85 *	    both a sed(1) and ed(1) :EDIT:; the :EDIT: action is usually
86 *	    specified using the here syntax to avoid make comment, quote and
87 *	    variable expansion
88 */
89
90.CONVERT.ID. = "@(#)$Id: CONVERT (AT&T Research) 2004-03-19 $"
91
92set nojobs noscan nowriteobject writestate=$$(MAKEFILE).ms
93
94package = $(PWD:B)
95here = !-=-=-=-=-!
96hierarchy = src src/cmd src/lib
97omit = .*|*.?(l)[ao]
98original = $(MAKEFILE:D)
99showedit = $(-debug:?p??)
100
101CPFLAGS = -u
102PAXFLAGS = -u -v
103STDEDFLAGS = -
104TW = tw
105TWFLAGS = -CP
106
107all  : .VIRTUAL file
108file : .VIRTUAL edit
109edit : .VIRTUAL copy
110copy : .VIRTUAL init
111init : .VIRTUAL
112
113.MAKEINIT : .cvt.init
114
115.cvt.init : .MAKE .VIRTUAL .FORCE
116	local D
117	if D = "$(~.ARGS:O=1)"
118		if "$(D:T>FD)"
119			original := $(D)
120			.ARGS : .CLEAR $(~.ARGS:O>1)
121		end
122	end
123
124.cvt.filter =
125.cvt.package =
126
127.cvt.atom : .FUNCTION
128	local N V
129	V := $(%:O=1)
130	let .cvt.$(V) = .cvt.$(V) + 1
131	return .cvt.$(V).$(.cvt.$(V))
132
133.cvt.omit : .FUNCTION
134	return -s',^\(\(?K)?(*/)($(omit))?(/*))$,,$(showedit)'
135
136.cvt.to : .FUNCTION
137	if "$(%)" == "."
138		return src
139	end
140	if "$(%)" == "*/*"
141		return src/$(%)
142	end
143	if "$(%)" == "lib*"
144		return src/lib/$(%)
145	end
146	return src/cmd/$(%)
147
148":CONVERT:" : .MAKE .OPERATOR
149	local I
150	package := $(<)
151	I := $(hierarchy:C,$,/Makefile)
152	init : .cvt.verify $(I)
153	$(I) : .ACCEPT
154		test -d $(<:D) || $(MKDIR) -p $(<:D)
155		echo :MAKE: > $(<)
156	.cvt.verify : .MAKE .FORCE .REPEAT
157		local I
158		if I = "$(.cvt.package:T!=F)"
159			error 3 $(original): not a $(package) source directory: missing $(I)
160		end
161	.cvt.package := $(>:C,^,$$(original)/,)
162
163":COPY:" : .MAKE .OPERATOR
164	local F T I A
165	F := $(>:O=1)
166	T := $(.cvt.to $(>:O=2))
167	A := $(.cvt.atom copy)
168	copy : $(A)
169	$(A) : .VIRTUAL
170	if F == "."
171		$(A) : $(T)
172		$(T) :
173			test -d $(<) || $(MKDIR) -p $(<)
174		for I $(>:O>2)
175			eval
176			$$(A) : $(I:D=$(T):B:S)
177			$(I:D=$(T):B:S) : $$(original)/$(I)
178				$$(CP) $$(CPFLAGS) $$(*) $$(<)
179			end
180		end
181	elif "$(F:T=FF)" || "$(F:N=*.(pax|t[bg]z))"
182		eval
183		$$(A) : $$(F)
184			test -d $(T) || $$(MKDIR) -p $(T)
185			cd $(T)
186			$$(PAX) $$(PAXFLAGS) -rf $$(*:P=A) -s ',^$(>:O=2)/*,,' $(.cvt.omit) $(.cvt.filter)
187		end
188	else
189		F := $$(original)/$(F)
190		if ! "$(@:V)"
191			eval
192			$$(A) : .FORCE
193				test -d $(T) || $$(MKDIR) -p $(T)
194				cd $(F:V)
195				$$(TW) $$(TWFLAGS) | $$(PAX) $$(PAXFLAGS) -rw $(.cvt.omit) $(.cvt.filter) $(T:P=A)
196			end
197		else
198			.cvt.move =
199			: $(@:V:@R)
200			eval
201			$$(A) : .FORCE
202				test -d $(T) || $$(MKDIR) -p $(T)
203				cd $(F:V)
204				$$(TW) $$(TWFLAGS) | $$(PAX) $$(PAXFLAGS) -rw $(.cvt.omit) $(.cvt.move) $(.cvt.filter) $(T:P=A)
205			end
206		end
207	end
208
209":EDIT:" : .MAKE .OPERATOR
210	local A D F
211	D := $(>:O=1)
212	if D == "-"
213		A := ^$(>:O=2)^$$(SED) -e $(@:Q:/'\n'/ -e /G)
214		.cvt.filter += --action=$(A:@Q)
215	else
216		D := $(.cvt.to $(D))
217		F := $(>:O>1:C,^,$(D)/,)
218		edit : $(F)
219		eval
220		$$(F) :
221			$$(STDED) $$(STDEDFLAGS) $$(<) <<'$(here)'
222			$(@:V)
223			w
224			q
225			$(here)
226		end
227	end
228
229":FILE:" : .MAKE .OPERATOR
230	local ( D F ) $(>)
231	local A
232	A := $(.cvt.atom file)
233	$(A) := $(@:V)
234	D := $(.cvt.to $(D))
235	file : $(D)/$(F)
236	eval
237	$$(D)/$$(F) :
238		test -d $$(<:D) || $$(MKDIR) -p $$(<:D)
239		cat > $$(<) <<'$(here)'
240		$$($(A):V)
241		$(here)
242	end
243
244":MOVE:" : .MAKE .OPERATOR
245	local T I
246	T := ../../../$(.cvt.to $(>:O=1))
247	for I $(>:O>1)
248		if I == "*/"
249			.cvt.move += -s',^\(\(?K)$(I)),$(T)/,$(showedit)'
250			.cvt.move += -s',^\(\(?K)$(I:C%/$%%))$,,$(showedit)'
251		else
252			.cvt.move += -s',^\(\(?K)$(I))$,$(T)/$(I:B:S),$(showedit)'
253		end
254	end
255
256":OMIT:" : .MAKE .OPERATOR
257	local P
258	for P $(>)
259		omit := $(omit)|$(P)
260	end
261