home *** CD-ROM | disk | FTP | other *** search
- /* build in E.
-
- TODO: - cyclic structure check
- - (amigados?) constants
-
- */
-
- OPT OSVERSION=37
-
- MODULE 'tools/file', 'dos/dosextens', 'dos/dos'
-
- /* object: dep1 dep2 ....
- act1
- act2
- */
-
- OBJECT object
- next:PTR TO object
- name:PTR TO CHAR
- firstdep:PTR TO dependancy
- firstaction:PTR TO action
- child
- ENDOBJECT
-
- OBJECT dependancy
- next:PTR TO dependancy
- object:PTR TO object
- ENDOBJECT
-
- OBJECT action
- next:PTR TO action
- comstring:PTR TO CHAR
- ENDOBJECT
-
- OBJECT arg
- target,buildfile,force
- ENDOBJECT
-
- DEF curline=0, curstring, uptodate=TRUE, args:PTR TO arg
-
- PROC main() HANDLE
- DEF m,l,buildfile[200]:STRING,rdargs=NIL
- NEW args
- IF (rdargs:=ReadArgs('TARGET,FROM/K,FORCE/S',args,NIL))=NIL THEN Raise("barg")
- IF args.buildfile THEN StrCopy(buildfile,args.buildfile)
- StrAdd(buildfile,'.build')
- PrintF('E Build v0.8 (c) 1993 Rob and Wouter (processing "\s")\n',buildfile)
- m,l:=readfile(buildfile)
- buildtree(parse(stringsinfile(m,l,countstrings(m,l))))
- IF uptodate THEN PrintF('All files are up to date.\n')
- Raise()
- EXCEPT
- IF rdargs THEN FreeArgs(rdargs)
- IF exception=0 THEN RETURN
- PrintF('Error: ')
- SELECT exception
- CASE "OPEN"
- PrintF('couldn''t open "\s".\n',exceptioninfo)
- CASE "MEM"
- PrintF('not enough memory.\n')
- CASE "IN"
- PrintF('couldn''t read file.\n')
- CASE "nobj"
- PrintF('action without object.\n')
- CASE "fexp"
- PrintF('filename expected.\n')
- CASE "dexp"
- PrintF('":" expected.\n')
- CASE "empt"
- PrintF('nothing to build.\n')
- CASE "circ"
- PrintF('circular dependancies between files.\n')
- CASE "bada"
- PrintF('action failed to build "\s".\n',exceptioninfo)
- CASE "badd"
- PrintF('dependancy "\s" not available.\n',exceptioninfo)
- CASE "derr"
- PrintF('child process failed.\n')
- CASE "ntar"
- PrintF('no such target: "\s"\n',args.target)
- CASE "ndep"
- PrintF('no dependancies for object "\s".\n',exceptioninfo)
- CASE "barg"
- PrintFault(IoErr(),NIL)
- DEFAULT
- PrintF('burp.\n')
- ENDSELECT
- IF curline THEN PrintF('at line: (\d) "\s"\n',curline,curstring)
- IF exception THEN PrintF('Build terminated\n')
- RETURN 10
- ENDPROC
-
- PROC parse(list:PTR TO LONG)
- DEF l=NIL:PTR TO object, s, c, i, t
- FOR curline:=0 TO ListLen(list)-1
- s:=list[curline]
- curstring:=s
- c:=s[]
- IF (c<>"#") AND (c<>"\0") -> ignore?
- IF (c=" ") OR (c="\t") -> action
- s:=eatwhite(s)
- IF s[]
- IF l=NIL THEN Raise("nobj")
- l.firstaction:=NEW [l.firstaction,s]:action
- ENDIF
- ELSE -> object rule
- i:=s
- s:=eatname(s)
- IF s=i THEN Raise("fexp")
- t:=s
- s:=eatwhite(s)
- IF s[]++<>":" THEN Raise("dexp")
- t[]:="\0"
- l:=NEW [l,i,NIL,NIL,0]:object
- s:=eatwhite(s)
- IF s[]<>"\0"
- REPEAT
- i:=s
- s:=eatname(s)
- t:=s
- IF t=i THEN Raise("fexp")
- s:=eatwhite(s)
- t[]:="\0"
- l.firstdep:=NEW [l.firstdep,i]:dependancy
- UNTIL s[]="\0"
- ENDIF
- ENDIF
- ENDIF
- ENDFOR
- curline:=0
- IF l=NIL THEN Raise("empt")
- ENDPROC l
-
- PROC eatwhite(s)
- WHILE (s[]=" ") OR (s[]="\t") DO s++
- ENDPROC s
-
- PROC eatname(s)
- WHILE (s[]<>" ") AND (s[]<>"\t") AND (s[]<>"\0") AND (s[]<>":") DO s++
- ENDPROC s
-
- PROC execute(c)
- PrintF('\t\s\n',c)
- uptodate:=FALSE
- IF Execute(c,NIL,stdout)=NIL THEN Raise("derr")
- ENDPROC
-
- PROC filetime(name:PTR TO CHAR)
- DEF l:PTR TO filelock, fib:fileinfoblock, date:PTR TO datestamp
- IF l:=Lock(name,ACTION_READ)
- IF Examine(l,fib)
- date:=fib.datestamp
- IF fib.direntrytype<0
- UnLock(l)
- RETURN date.days, Shl(date.minute,12)+date.tick
- ENDIF
- ENDIF
- UnLock(l)
- ENDIF
- ENDPROC -1
-
- PROC timelater(day1,tick1,day2,tick2)
- IF day1>day2
- RETURN TRUE
- ELSEIF day1=day2
- RETURN tick1>tick2
- ENDIF
- ENDPROC FALSE
-
- /*----------------rob's-stuff-------------------*/
-
- PROC buildtree(list:PTR TO object) -> returns root of tree
- DEF dep:PTR TO dependancy,
- obj:PTR TO object
-
- obj:=list
- WHILE obj -> traverse objects
- dep:=obj.firstdep
- WHILE dep -> traverse dependencies
- dep.object:=findobject(dep.object,list)
- dep:=dep.next
- ENDWHILE
- obj:=obj.next
- ENDWHILE
-
- -> CHECK CYCLES!!!
-
- obj:=list
- IF args.target
- WHILE obj
- IF StrCmp(args.target,obj.name) THEN JUMP out
- obj:=obj.next
- ENDWHILE
- Raise("ntar")
- out:
- ELSE
- IF obj THEN WHILE obj.next DO obj:=obj.next
- ENDIF
- traverse(obj)
- ENDPROC
-
-
- -> find object in list of objects by name
- PROC findobject(name:PTR TO CHAR,list:PTR TO object)
- WHILE list
- IF StrCmp(name,list.name)
- -> remove object from root list
- list.child:=TRUE;
- RETURN list
- ENDIF
- list:=list.next
- ENDWHILE
- ENDPROC NEW [NIL,name,NIL,NIL]:object
-
- -> child-first traversal of dependancy tree
- PROC traverse(obj:PTR TO object) -> executes actions in tree
- DEF dep:PTR TO dependancy,maxtime1=0,maxtime2=0,time1,time2,action:PTR TO action
-
- IF obj.firstdep OR obj.firstaction -> object with dependancies/actions
- -> traverse children and get maximum timestamp
- dep:=obj.firstdep
- WHILE dep
- time1,time2:=traverse(dep.object)
- IF timelater(time1,time2,maxtime1,maxtime2)
- maxtime1:=time1
- maxtime2:=time2
- ENDIF
- dep:=dep.next
- ENDWHILE
- time1,time2:=filetime(obj.name)
- IF time1<0 OR timelater(maxtime1,maxtime2,time1,time2) OR args.force
- -> dependancy file(s) more recent: build object
- -> execute actions
- action:=obj.firstaction
- WHILE action
- execute(action.comstring)
- action:=action.next
- ENDWHILE
- time1,time2:=filetime(obj.name)
- IF (time1<0) AND (obj.child=TRUE) THEN Throw("bada",obj.name)
- ENDIF
- RETURN time1,time2
- ENDIF
- -> object requires no action: return timestamp
- time1,time2:=filetime(obj.name);
- IF time1<0 THEN Throw("badd",obj.name)
- ENDPROC time1,time2
-