/*
* system / subsystem support
*
* lhs is subsystem directory name
* rhs is list of subsystem source file names relative to lhs
* no* entries disable subsystem prerequisites
* SS.MAIN is set to the first subsystem and its option table
* controls all other subsystems
*
* rhs supports 2 { ... } grouping forms
*
* { lhs-identifier ... : rhs-file ... }
*
* if any lhs-identifier is selected then rhs-file selected
*
* { rhs-file ... }
*
* rhs-file always selected
*
* table options are controlled by specifiying no lhs
* the default setting is in $(SS.TABLE)
* to clear or reset a table option
*
* :SYSTEM: nostate nomap format=lower
*
* no lhs and no rhs clears SS.MAIN
*/
if "$(<)"
.ASSERT : ":_SS_ASSERT_:"
if "$(>)" || "$(@:V)" || "$(<:N=*$(CC.SUFFIX.OBJECT))"
$$(<) :SS: $$(>)
$(@:V)
else
else if "$(>)"
local I N O P
for I $(>)
if I == "?(no)(format|map|state)?(=*)"
O := $(I:/no//)
if I != "no*"
else if I == "?(no)(caller|exclude|intercept)?([-+]=*)"
O := $(I:/no//)
N := SS.$(O:/[-+]*=.*//:F=%(upper)s)
P := $(O:/[^-+=]*[-+]*=//)
O := $(O:/$(P)//)
T := $(O:/[-+]*=//)
O := $(O:/$(T)//)
if I == "no*"
O = =
P =
else if ! O
O = =
P = 1
if O == "="
$(N) := $(P)
else if O == "+="
if ! "$($(N):N=$$(P))"
$(N) += $(P)
else
$(N) := $($(N):N!=$$(P))
else
else
SS := $(<:O=1)
if ! DD
DD = .
else if DD == "-"
else
if "$(SS:D)" != "."
else
if ! "$(Y:N=$(SS:B))"
if "$(N:N=$(SS:B))" || "$(Y:N=no$(SS:B))" || "$(Y:N=NO$(SS:B))"
else if "$(>)" || "$(@:V)" || "$(SS:N=*$(CC.SUFFIX.OBJECT))"
else
else
if "$(@:V)" || "$(SS:N=*$(CC.SUFFIX.OBJECT))"
G := $(SS)
if ! "$(>)" && ! "$(@:V)"
else
S = R
for I $(N)
if I == "-"
break
if I == "{"
if S != "R"
S = T
T =
P =
else if I == ":"
if S == "T"
S = P
else
else if I == "}"
if S == "P"
S = R
if "$(N:N=$(T:/ /|/G))"
R += $(P)
else if S == "T"
S = R
else
else
$(S) += $(I)
if S != "R"
P =
for I $(R)
if "$(I:A=.ATTRIBUTE)" || "$(I)" == "*=*"
P += $(I)
else
S := $(I:D)
if ! "$(I:A=.TARGET)"
if "$(I:S)"
P += $(I:D=$(S):B:S)
else
R =
P =
S = R
for I $(>) $(Y)
if I == "-"
break
if I == "{"
if S != "R"
S = T
T =
P =
else if I == ":"
if S == "T"
S = P
else
else if I == "}"
if S == "P"
S = R
T := $(T:/ /|/G)
while I == "*.*"
if "$($(I):N=$(T))"
R += $(P)
break
I := $(I:B)
else if S == "T"
S = R
R += $(T)
M += $(T)
else
else
$(S) += $(I)
if S != "R"
if ! M
return
R := $(M)
P =
for I $(R)
if "$(I:A=.ATTRIBUTE)" || "$(I)" == "*=*"
P += $(I)
else
S := $(I:D)
if ! "$(I:A=.TARGET)"
if "$(I:S)"
P += $(I:D=$(S):B:S)
else
$$(G) :: $$(P)
$(@:V)
else
T := $(SS)
while 1
T := $(T:D)
if T == "$(DD)"
break
G := $(T)
if "$(SS.CURRENT)" && ! "$(SS:A=.IMMEDIATE)" && ( ! "$(%%:A=.MAKE|.IMMEDIATE)" || "$(%%)" == "$(SS.CALLER:/ /|/G)" ) && "$(%)" == "$(SS.INTERCEPT:/ /|/G))"
local I T P
for I $(<)
if "$(I:A=.ATTRIBUTE|.TARGET)" && ! "$(I:D=$$(SS.CURRENT):B:S:A=.TARGET)"
T += $(I)
else
for I $(>)
if I == "*=*|/*" || "$(I:A=.ATTRIBUTE|.TARGET)"
P += $(I)
else
$$(T) $(%) $$(P)
$(@:V)
else
$$(<) $(%) $$(>)
$(@:V)