Index: waflib/Tools/tex.py
===================================================================
--- waflib/Tools/tex.py	(revision c101fe139c5f96364e9d3d18734eafd64d7b7618)
+++ waflib/Tools/tex.py	(revision 904702d027b3e5e51e28a12383eecea0b55611da)
@@ -4,5 +4,5 @@
 
 import os,re
-from waflib import Utils,Task,Errors,Logs
+from waflib import Utils,Task,Errors,Logs,Node
 from waflib.TaskGen import feature,before_method
 re_bibunit=re.compile(r'\\(?P<type>putbib)\[(?P<file>[^\[\]]*)\]',re.M)
@@ -15,5 +15,5 @@
 		path=match.group('file')
 		if path:
-			for k in['','.bib']:
+			for k in('','.bib'):
 				Logs.debug('tex: trying %s%s'%(path,k))
 				fi=node.parent.find_resource(path+k)
@@ -24,8 +24,9 @@
 	Logs.debug("tex: found the following bibunit files: %s"%nodes)
 	return nodes
-exts_deps_tex=['','.ltx','.tex','.bib','.pdf','.png','.eps','.ps']
+exts_deps_tex=['','.ltx','.tex','.bib','.pdf','.png','.eps','.ps','.sty']
 exts_tex=['.ltx','.tex']
-re_tex=re.compile(r'\\(?P<type>include|bibliography|putbib|includegraphics|input|import|bringin|lstinputlisting)(\[[^\[\]]*\])?{(?P<file>[^{}]*)}',re.M)
+re_tex=re.compile(r'\\(?P<type>usepackage|RequirePackage|include|bibliography([^\[\]{}]*)|putbib|includegraphics|input|import|bringin|lstinputlisting)(\[[^\[\]]*\])?{(?P<file>[^{}]*)}',re.M)
 g_bibtex_re=re.compile('bibdata',re.M)
+g_glossaries_re=re.compile('\\@newglossary',re.M)
 class tex(Task.Task):
 	bibtex_fun,_=Task.compile_fun('${BIBTEX} ${BIBTEXFLAGS} ${SRCFILE}',shell=False)
@@ -37,6 +38,11 @@
 	Execute the program **makeindex**
 	"""
+	makeglossaries_fun,_=Task.compile_fun('${MAKEGLOSSARIES} ${SRCFILE}',shell=False)
+	makeglossaries_fun.__doc__="""
+	Execute the program **makeglossaries**
+	"""
 	def exec_command(self,cmd,**kw):
 		bld=self.generator.bld
+		Logs.info('runner: %r'%cmd)
 		try:
 			if not kw.get('cwd',None):
@@ -72,4 +78,11 @@
 			global re_tex
 			for match in re_tex.finditer(code):
+				multibib=match.group('type')
+				if multibib and multibib.startswith('bibliography'):
+					multibib=multibib[len('bibliography'):]
+					if multibib.startswith('style'):
+						continue
+				else:
+					multibib=None
 				for path in match.group('file').split(','):
 					if path:
@@ -77,6 +90,9 @@
 						found=None
 						for k in exts_deps_tex:
-							Logs.debug('tex: trying %s%s'%(path,k))
-							found=node.parent.find_resource(path+k)
+							for up in self.texinputs_nodes:
+								Logs.debug('tex: trying %s%s'%(path,k))
+								found=up.find_resource(path+k)
+								if found:
+									break
 							for tsk in self.generator.tasks:
 								if not found or found in tsk.outputs:
@@ -89,4 +105,9 @@
 										parse_node(found)
 										break
+							if found and multibib and found.name.endswith('.bib'):
+								try:
+									self.multibibs.append(found)
+								except AttributeError:
+									self.multibibs=[found]
 						if add_name:
 							names.append(path)
@@ -103,14 +124,20 @@
 			try:
 				ct=aux_node.read()
-			except(OSError,IOError):
+			except EnvironmentError:
 				Logs.error('Error reading %s: %r'%aux_node.abspath())
 				continue
 			if g_bibtex_re.findall(ct):
-				Logs.warn('calling bibtex')
+				Logs.info('calling bibtex')
 				self.env.env={}
 				self.env.env.update(os.environ)
-				self.env.env.update({'BIBINPUTS':self.TEXINPUTS,'BSTINPUTS':self.TEXINPUTS})
+				self.env.env.update({'BIBINPUTS':self.texinputs(),'BSTINPUTS':self.texinputs()})
 				self.env.SRCFILE=aux_node.name[:-4]
 				self.check_status('error when calling bibtex',self.bibtex_fun())
+		for node in getattr(self,'multibibs',[]):
+			self.env.env={}
+			self.env.env.update(os.environ)
+			self.env.env.update({'BIBINPUTS':self.texinputs(),'BSTINPUTS':self.texinputs()})
+			self.env.SRCFILE=node.name[:-4]
+			self.check_status('error when calling bibtex',self.bibtex_fun())
 	def bibunits(self):
 		try:
@@ -120,19 +147,20 @@
 		else:
 			if bibunits:
-				fn=['bu'+str(i)for i in xrange(1,len(bibunits)+1)]
+				fn=['bu'+str(i)for i in range(1,len(bibunits)+1)]
 				if fn:
-					Logs.warn('calling bibtex on bibunits')
+					Logs.info('calling bibtex on bibunits')
 				for f in fn:
-					self.env.env={'BIBINPUTS':self.TEXINPUTS,'BSTINPUTS':self.TEXINPUTS}
+					self.env.env={'BIBINPUTS':self.texinputs(),'BSTINPUTS':self.texinputs()}
 					self.env.SRCFILE=f
 					self.check_status('error when calling bibtex',self.bibtex_fun())
 	def makeindex(self):
+		self.idx_node=self.inputs[0].change_ext('.idx')
 		try:
 			idx_path=self.idx_node.abspath()
 			os.stat(idx_path)
 		except OSError:
-			Logs.warn('index file %s absent, not calling makeindex'%idx_path)
+			Logs.info('index file %s absent, not calling makeindex'%idx_path)
 		else:
-			Logs.warn('calling makeindex')
+			Logs.info('calling makeindex')
 			self.env.SRCFILE=self.idx_node.name
 			self.env.env={}
@@ -142,4 +170,23 @@
 		if os.path.exists(os.path.join(p.abspath(),'btaux.aux')):
 			self.aux_nodes+=p.ant_glob('*[0-9].aux')
+	def makeglossaries(self):
+		src_file=self.inputs[0].abspath()
+		base_file=os.path.basename(src_file)
+		base,_=os.path.splitext(base_file)
+		for aux_node in self.aux_nodes:
+			try:
+				ct=aux_node.read()
+			except EnvironmentError:
+				Logs.error('Error reading %s: %r'%aux_node.abspath())
+				continue
+			if g_glossaries_re.findall(ct):
+				if not self.env.MAKEGLOSSARIES:
+					raise Errors.WafError("The program 'makeglossaries' is missing!")
+				Logs.warn('calling makeglossaries')
+				self.env.SRCFILE=base
+				self.check_status('error when calling makeglossaries %s'%base,self.makeglossaries_fun())
+				return
+	def texinputs(self):
+		return os.pathsep.join([k.abspath()for k in self.texinputs_nodes])+os.pathsep
 	def run(self):
 		env=self.env
@@ -148,39 +195,38 @@
 			env.append_value('PDFLATEXFLAGS','-interaction=batchmode')
 			env.append_value('XELATEXFLAGS','-interaction=batchmode')
-		fun=self.texfun
-		node=self.inputs[0]
-		srcfile=node.abspath()
-		texinputs=self.env.TEXINPUTS or''
-		self.TEXINPUTS=node.parent.get_bld().abspath()+os.pathsep+node.parent.get_src().abspath()+os.pathsep+texinputs+os.pathsep
 		self.cwd=self.inputs[0].parent.get_bld().abspath()
-		Logs.warn('first pass on %s'%self.__class__.__name__)
-		self.env.env={}
-		self.env.env.update(os.environ)
-		self.env.env.update({'TEXINPUTS':self.TEXINPUTS})
-		self.env.SRCFILE=srcfile
-		self.check_status('error when calling latex',fun())
-		self.aux_nodes=self.scan_aux(node.change_ext('.aux'))
-		self.idx_node=node.change_ext('.idx')
+		Logs.info('first pass on %s'%self.__class__.__name__)
+		cur_hash=self.hash_aux_nodes()
+		self.call_latex()
+		self.hash_aux_nodes()
 		self.bibtopic()
 		self.bibfile()
 		self.bibunits()
 		self.makeindex()
-		hash=''
+		self.makeglossaries()
 		for i in range(10):
-			prev_hash=hash
+			prev_hash=cur_hash
+			cur_hash=self.hash_aux_nodes()
+			if not cur_hash:
+				Logs.error('No aux.h to process')
+			if cur_hash and cur_hash==prev_hash:
+				break
+			Logs.info('calling %s'%self.__class__.__name__)
+			self.call_latex()
+	def hash_aux_nodes(self):
+		try:
+			nodes=self.aux_nodes
+		except AttributeError:
 			try:
-				hashes=[Utils.h_file(x.abspath())for x in self.aux_nodes]
-				hash=Utils.h_list(hashes)
-			except(OSError,IOError):
-				Logs.error('could not read aux.h')
-				pass
-			if hash and hash==prev_hash:
-				break
-			Logs.warn('calling %s'%self.__class__.__name__)
-			self.env.env={}
-			self.env.env.update(os.environ)
-			self.env.env.update({'TEXINPUTS':self.TEXINPUTS})
-			self.env.SRCFILE=srcfile
-			self.check_status('error when calling %s'%self.__class__.__name__,fun())
+				self.aux_nodes=self.scan_aux(self.inputs[0].change_ext('.aux'))
+			except IOError:
+				return None
+		return Utils.h_list([Utils.h_file(x.abspath())for x in self.aux_nodes])
+	def call_latex(self):
+		self.env.env={}
+		self.env.env.update(os.environ)
+		self.env.env.update({'TEXINPUTS':self.texinputs()})
+		self.env.SRCFILE=self.inputs[0].abspath()
+		self.check_status('error when calling latex',self.texfun())
 class latex(tex):
 	texfun,vars=Task.compile_fun('${LATEX} ${LATEXFLAGS} ${SRCFILE}',shell=False)
@@ -204,5 +250,5 @@
 @before_method('process_source')
 def apply_tex(self):
-	if not getattr(self,'type',None)in['latex','pdflatex','xelatex']:
+	if not getattr(self,'type',None)in('latex','pdflatex','xelatex'):
 		self.type='pdflatex'
 	tree=self.bld
@@ -212,10 +258,13 @@
 	if getattr(self,'deps',None):
 		deps=self.to_list(self.deps)
-		for filename in deps:
-			n=self.path.find_resource(filename)
-			if not n:
-				self.bld.fatal('Could not find %r for %r'%(filename,self))
-			if not n in deps_lst:
-				deps_lst.append(n)
+		for dep in deps:
+			if isinstance(dep,str):
+				n=self.path.find_resource(dep)
+				if not n:
+					self.bld.fatal('Could not find %r for %r'%(dep,self))
+				if not n in deps_lst:
+					deps_lst.append(n)
+			elif isinstance(dep,Node.Node):
+				deps_lst.append(dep)
 	for node in self.to_nodes(self.source):
 		if self.type=='latex':
@@ -227,21 +276,33 @@
 		task.env=self.env
 		if deps_lst:
-			try:
-				lst=tree.node_deps[task.uid()]
-				for n in deps_lst:
-					if not n in lst:
-						lst.append(n)
-			except KeyError:
-				tree.node_deps[task.uid()]=deps_lst
-		v=dict(os.environ)
-		p=node.parent.abspath()+os.pathsep+self.path.abspath()+os.pathsep+self.path.get_bld().abspath()+os.pathsep+v.get('TEXINPUTS','')+os.pathsep
-		v['TEXINPUTS']=p
+			for n in deps_lst:
+				if not n in task.dep_nodes:
+					task.dep_nodes.append(n)
+		if hasattr(self,'texinputs_nodes'):
+			task.texinputs_nodes=self.texinputs_nodes
+		else:
+			task.texinputs_nodes=[node.parent,node.parent.get_bld(),self.path,self.path.get_bld()]
+			lst=os.environ.get('TEXINPUTS','')
+			if self.env.TEXINPUTS:
+				lst+=os.pathsep+self.env.TEXINPUTS
+			if lst:
+				lst=lst.split(os.pathsep)
+			for x in lst:
+				if x:
+					if os.path.isabs(x):
+						p=self.bld.root.find_node(x)
+						if p:
+							task.texinputs_nodes.append(p)
+						else:
+							Logs.error('Invalid TEXINPUTS folder %s'%x)
+					else:
+						Logs.error('Cannot resolve relative paths in TEXINPUTS %s'%x)
 		if self.type=='latex':
 			if'ps'in outs:
 				tsk=self.create_task('dvips',task.outputs,node.change_ext('.ps'))
-				tsk.env.env=dict(v)
+				tsk.env.env=dict(os.environ)
 			if'pdf'in outs:
 				tsk=self.create_task('dvipdf',task.outputs,node.change_ext('.pdf'))
-				tsk.env.env=dict(v)
+				tsk.env.env=dict(os.environ)
 		elif self.type=='pdflatex':
 			if'ps'in outs:
@@ -250,5 +311,5 @@
 def configure(self):
 	v=self.env
-	for p in'tex latex pdflatex xelatex bibtex dvips dvipdf ps2pdf makeindex pdf2ps'.split():
+	for p in'tex latex pdflatex xelatex bibtex dvips dvipdf ps2pdf makeindex pdf2ps makeglossaries'.split():
 		try:
 			self.find_program(p,var=p.upper())
