4.3BSD/usr/contrib/icon/src/cmd/cppp.icn

#	CPPP(1)
#
#	Expand C conditionals
#
#	Ralph E. Griswold
#
#	Last modified 8/14/84
#

procedure main(x)
   local s, line, name, alist, dlist, ulist, process, ptype, delete
   dlist := []				# list of things to be defined
   ulist := []				# list of things to be undefined
   delete := string			#  efficient no-op
   every s := !x do			#  process options
      if s == "-d" then alist := dlist
      else if s == "-u" then alist := ulist
      else put(\alist,s) | stop("usage: [-d names ] [-u names ]")
   process := write			# accept by default
   name := []				# stack of defined names
   ptype := [write]			# stack of processes
   while line := read() do
      if line[1] ~== "#" then process(line)
      else if line ?
         (conditional("define" | "undef") == (!dlist | !ulist)) then next
      else if line ? (push(name,conditional("ifdef"))) then {
         push(ptype,process)
         if name[1] == !dlist then process := write
         else if name[1] == !ulist then process := delete
         else process(line)
         }
      else if line ? conditional("endif") then {
         if not(name[1] == (!dlist | !ulist)) then process(line)
         pop(name)
         process := pop(ptype)
         }
      else if line ? (push(name,conditional("ifndef"))) then {
         push(ptype,process)
         if name[1] == !ulist then process := write
         else if name[1] == !dlist then process := delete
         else process(line)
         }
      else if line ? conditional("else") then {
         if name[1] == !dlist then process := delete
         else if name[1] == !ulist then process := write
         else process(line)
         }
      else process(line)
end

#  look for conditional line
#
procedure conditional(type)
   static ws
   initial ws := ' \t'
   return {
      ="#" &
      (tab(many(ws)) | "") &
      =type &
      (tab(many(ws)) | "") &
      tab(upto(ws) | 0)
      }
end