cosmetix in Jambase
[k8jam.git] / defaults / misc / fsys / Jambase.misc.fsys
blobe46aa1ef5b6d0018ba325839b357791f63a6f03a
1 rule IsRootDir {
2   local res = ;
3   #
4   # handle "C:", "C:/", "/cygdrive" and "/cygdrive/" in Cygwin
5   if $(NT) {
6     switch $(<) {
7       case "*:"  : res = "1" ;
8       case '*:\' : res = "1" ;
9     }
10   } else if $(UNIX) && $(OS) = CYGWIN {
11     switch $(<) {
12       case "?:"  : res = "1" ;
13       case "?:/" : res = "1" ;
14       case "/cygdrive"  : res = "1" ;
15       case "/cygdrive/" : res = "1" ;
16     }
17   } else if $(<) = "/" || $(<) = $(<:P) {
18     res = "1" ;
19   }
20   #
21   return $(res) ;
25 rule RemoveTrailingSlashes {
26   if ! [ IsRootDir $(<[1]) ] {
27     local mt = [ Match '^(.*?)/+$' : $(<[1]) ] ;
28     if $(mt) { return $(mt[1]) ; }
29   }
30   return $(<[1]) ;
34 rule AddTrailingSlash {
35   local _ttt = $(<[1]) ;
36   if $(_ttt) {
37     if ! ( $(_ttt) ~= '[/]$' ) { _ttt = "$(_ttt)/" ; }
38   } else {
39     _ttt = "" ;
40   }
41   return $(_ttt) ;
45 # $(2): return empty as "."
46 rule FDirNormalizeDots {
47   local _d = [ RemoveTrailingSlashes $(<) ] ;
48   #
49   if ! $(_d) {
50     if $(2) { _d = "." ; } else { _d = ; }
51   } else if ! [ IsRootDir $(_d) ] {
52     local _t = $(_d:D=) ;
53     local _p = [ RemoveTrailingSlashes $(_d:P) ] ;
54     #
55     if $(_t) = $(DOT) {
56       _d = [ FDirNormalizeDots $(_p) ] ;
57     } else {
58       _d = [ FDirNormalizeDots $(_p) ] ;
59       _d += $(_t) ;
60       if $(_d[1]) = "/" && $(_d[1]) = "/" { _d = "" $(_d[2-]) ; }
61     }
62   }
63   _d = $(_d:J=$(PATH_SEPARATOR)) ;
64   return $(_d) ;
68 # $(2): return empty as "."
69 rule FDirNormalizeI {
70   local _d = [ RemoveTrailingSlashes $(<) ] ;
71   #
72   #Echo "FDirNormalizeI:" "$(_d)" ;
73   #
74   if ! $(_d) {
75     if $(2) { _d = "." ; } else { _d = ; }
76   } else if ! [ IsRootDir $(_d) ] {
77     local _t = $(_d:D=) ;
78     local _p = [ RemoveTrailingSlashes $(_d:P) ] ;
79     #
80     # check if we have only 'dotdots' here (fuck windoze and cygwin for now)
81     if $(_p) ~= '^(\.\.?/+)*\.\.?$' {
82       #Echo "DOTDOTS:" "$(_p)" ;
83       _d = $(_p) $(_t) ;
84     } else {
85       if $(_t) = $(DOTDOT) {
86         # ..
87         #Echo "XDOTDOT-I:" "$(_t)" ;
88         while 1 {
89           if [ IsRootDir $(_p) ] {
90             #Echo "XDOTDOT-R:" "$(_t)" "_p:" "$(_p)" ;
91             if ! $(_p) { _p = $(_t) ; }
92             #Echo "XDOTDOT-X:" "$(_p)" ;
93             return $(_p) ;
94           }
95           # cut one
96           _t = $(_p:D=) ;
97           _p = [ RemoveTrailingSlashes $(_p:P) ];
98           if $(_t) != $(DOT) { break ; }
99         }
100         #Echo "XDOTDOT-O:" "$(_t)" ;
101         _d = [ FDirNormalizeI $(_p) : $(2) ] ;
102       } else if $(_t) = $(DOT) {
103         # .
104         _d = [ FDirNormalizeI $(_p) : $(2) ] ;
105       } else {
106         _d = [ FDirNormalizeI $(_p) : $(2) ] ;
107         _d += $(_t) ;
108         if $(_d[1]) = "/" && $(_d[1]) = "/" { _d = "" $(_d[2-]) ; }
109       }
110     }
111   #} else {
112   #  Echo "ROOTDIR:" "$(_d)" ;
113   }
114   _d = $(_d:J=$(PATH_SEPARATOR)) ;
115   return $(_d) ;
119 # $2: return empty dir as "./"?
120 rule FDirNormalize {
121   #Echo "FDirNormalize-i:" "$(<)" ;
122   local res = [ FDirNormalizeDots $(<) : $(2) ] ;
123   res = [ FDirNormalizeI $(res) : $(2) ] ;
124   if ! $(res) && $(2) { res = "./" ; }
125   #Echo "FDirNormalize-o:" "$(res)" ;
126   return $(res) ;
130 # $2: return empty path as "./"?
131 rule FPathNormalize {
132   #Echo "FPathNormalize-i:" "$(<)" ;
133   local res = [ FDirNormalizeDots $(<) : $(2) ] ;
134   res = [ FDirNormalizeI $(res) : $(2) ] ;
135   #
136   if $(res) {
137     res += $(PATH_SEPARATOR) ;
138     res = $(res:J) ;
139   } else if $(2) {
140     res = "./" ;
141   }
142   #
143   #Echo "FPathNormalize-o:" "$(res)" ;
144   return $(res) ;
148 # /MkDir  dir ;
150 # Creates _dir_ and its parent directories
152 rule MkDirI {
153   # Ignore timestamps on directories: we only care if they exist.
154   NoUpdate $(<) ;
156   # Don't create . or any directory already created.
157   if $(<:G=) != $(DOT) && ! $($(<)-mkdir) {
158     # Cheesy gate to prevent multiple invocations on same dir
159     # Arrange for jam dirs
160     # MkDir1 has the actions
161     $(<)-mkdir = true ;
162     Depends dirs : $(<) ;
163     MkDir1 $(<) ;
165     # Recursively make parent directories.
166     # $(<:P) = $(<)'s parent, & we recurse until root
167     local s = $(<:P) ;
169     if [ IsRootDir $(s) ] { s = ; }
171     if $(s) = $(<) {
172       # The parent is the same as the dir.
173       # We're at the root, which some OS's can't stat, so we mark
174       # it as NotFile.
175       NotFile $(s) ;
176     } else if $(s:G=) {
177       # There's a parent; recurse.
178       Depends $(<) : $(s) ;
179       MkDirI $(s) ;
180     }
181   }
184 rule MkDir {
185   local d = $(<:G=) ;
186   NoUpdate $(<) ;
187   if $(d) && $(d) != $(DOT) && $(d) != $(DOTDOT) && ! $($(<)-mkdir) {
188     #Echo "$1:" "$(1)" ;
189     #Echo "MkDir0: $(d)" ;
190     d = [ FPathNormalize $(d) : tan ] ;
191     #Echo "MkDir1: $(d)" ;
192     d = $(<:G) $(d) ;
193     d = $(d:J) ;
194     #Echo "MkDir2: $(d)" ;
195     MkDirI $(d) ;
196   }
200 actions MkDir1 {
201   $(MKDIR) $(<)
205 # /Chmod target ;
207 # (Unix and VMS only). Change file permissions on _target_ to target-specific
208 # $(MODE) value set by @Link, @File, @Install* and @Shell rules
210 rule Chmod {
211   if $(CHMOD) { Chmod1 $(<) ; }
214 actions Chmod1 {
215   $(CHMOD) $(MODE) $(<)
219 actions Chown {
220   $(CHOWN) $(OWNER) $(<)
224 # /HardLink target : source ;
226 # Makes _target_ a hard link to _source_, if it isn't one already
227 # (Unix only)
229 rule HardLink {
230   Depends files : $(<) ;
231   Depends $(<) : $(>) ;
232   SEARCH on $(>) = $(SEARCH_SOURCE) ;
236 actions HardLink {
237   $(RM) $(<) && $(LN) $(>) $(<)
241 rule SoftLink {
242   Depends files : $(<) ;
243   Depends $(<) : $(>) ;
244   SEARCH on $(>) = $(SEARCH_SOURCE) ;
245   Clean clean : $(<) ;
248 actions SoftLink {
249   $(RM) $(<) && $(LN) -s $(>) $(<)
253 rule Shell {
254   Depends shell : $(<) ;
255   Depends $(<) : $(>) ;
256   SEARCH on $(>) = $(SEARCH_SOURCE) ;
257   MODE on $(<) = $(SHELLMODE) ;
258   Clean clean : $(<) ;
259   Chmod $(<) ;
262 #DONT_TOUCH
263 actions Shell {
264   $(AWK) '
265     NR == 1 { print "$(SHELLHEADER)" }
266     NR == 1 && /^[#:]/ { next }
267     /^##/ { next }
268     { print }
269   ' < $(>) > $(<)
271 #DONT_TOUCH
274 rule Setuid {
275   MODE on [ FAppendSuffix $(<) : $(SUFEXE) ] = 4711 ;
279 # /File target : source ;
281 # Copies _source_ into _target_
283 rule File {
284   Depends files : $(<) ;
285   Depends $(<) : $(>) ;
286   SEARCH on $(>) = $(SEARCH_SOURCE) ;
287   MODE on $(<) = $(FILEMODE) ;
288   Chmod $(<) ;
291 actions File {
292   $(CP) $(>) $(<)
296 # /Bulk  directory : sources ;
298 # Copies _sources_ into _directory_
300 rule Bulk {
301   local i ;
303   for i in $(>) {
304     File $(i:D=$(<)) : $(i) ;
305   }
309 rule FileExists names {
310   local _fn _lst _dir _name ;
312   for _fn in $(names) {
313     _dir = [ Match '^(.*?)/[^/]+$' : $(_fn) ] ;
314     _name = [ Match '^.*?/([^/]+)$' : $(_fn) ] ;
315     if ! $(_dir) { _dir = . ; }
316     #Echo "_dir:" $(_dir) ;
317     #Echo "_name:" $(_name) ;
318     _lst = [ Glob $(_dir) : $(_name) : plain files-only ] ;
319     #Echo "_lst:" $(_lst) ;
320     if ! $(_lst) { return ; }
321   }
322   return "tan" ;
326 rule DirExists names {
327   local _fn _lst _dir _name ;
329   for _fn in $(names) {
330     _dir = [ Match '^(.*?)/[^/]+$' : $(_fn) ] ;
331     _name = [ Match '^.*?/([^/]+)$' : $(_fn) ] ;
332     if ! $(_dir) { _dir = . ; }
333     #Echo "_dir:" $(_dir) ;
334     #Echo "_name:" $(_name) ;
335     _lst = [ Glob $(_dir) : $(_name) : plain dirs-only ] ;
336     #Echo "_lst:" $(_lst) ;
337     if ! $(_lst) { return ; }
338   }
339   return "tan" ;
343 # build list of files in directory and all subdirs
344 # prepends add file names with $(dir)
345 rule BuildFileList dir : mask {
346   local _lst = [ Glob $(dir) : $(mask) : files-only ] ;
347   local _dirs = [ Glob $(dir) : '[^_.]*' : dirs-only ] ;
348   local _dn _l ;
350   for _dn in $(_dirs) {
351     #Echo "dir:" $(_dn) ;
352     _l = [ BuildFileList $(_dn) : $(mask) ] ;
353     _lst += $(_l) ;
354   }
356   return $(_lst) ;