waf, waflib: update to 1.7.15
[aubio.git] / waflib / Tools / c_preproc.py
1 #! /usr/bin/env python
2 # encoding: utf-8
3 # WARNING! Do not edit! http://waf.googlecode.com/git/docs/wafbook/single.html#_obtaining_the_waf_file
4
5 import re,string,traceback
6 from waflib import Logs,Utils,Errors
7 from waflib.Logs import debug,error
8 class PreprocError(Errors.WafError):
9         pass
10 POPFILE='-'
11 recursion_limit=150
12 go_absolute=False
13 standard_includes=['/usr/include']
14 if Utils.is_win32:
15         standard_includes=[]
16 use_trigraphs=0
17 strict_quotes=0
18 g_optrans={'not':'!','and':'&&','bitand':'&','and_eq':'&=','or':'||','bitor':'|','or_eq':'|=','xor':'^','xor_eq':'^=','compl':'~',}
19 re_lines=re.compile('^[ \t]*(#|%:)[ \t]*(ifdef|ifndef|if|else|elif|endif|include|import|define|undef|pragma)[ \t]*(.*)\r*$',re.IGNORECASE|re.MULTILINE)
20 re_mac=re.compile("^[a-zA-Z_]\w*")
21 re_fun=re.compile('^[a-zA-Z_][a-zA-Z0-9_]*[(]')
22 re_pragma_once=re.compile('^\s*once\s*',re.IGNORECASE)
23 re_nl=re.compile('\\\\\r*\n',re.MULTILINE)
24 re_cpp=re.compile(r'//.*?$|/\*.*?\*/|\'(?:\\.|[^\\\'])*\'|"(?:\\.|[^\\"])*"',re.DOTALL|re.MULTILINE)
25 trig_def=[('??'+a,b)for a,b in zip("=-/!'()<>",r'#~\|^[]{}')]
26 chr_esc={'0':0,'a':7,'b':8,'t':9,'n':10,'f':11,'v':12,'r':13,'\\':92,"'":39}
27 NUM='i'
28 OP='O'
29 IDENT='T'
30 STR='s'
31 CHAR='c'
32 tok_types=[NUM,STR,IDENT,OP]
33 exp_types=[r"""0[xX](?P<hex>[a-fA-F0-9]+)(?P<qual1>[uUlL]*)|L*?'(?P<char>(\\.|[^\\'])+)'|(?P<n1>\d+)[Ee](?P<exp0>[+-]*?\d+)(?P<float0>[fFlL]*)|(?P<n2>\d*\.\d+)([Ee](?P<exp1>[+-]*?\d+))?(?P<float1>[fFlL]*)|(?P<n4>\d+\.\d*)([Ee](?P<exp2>[+-]*?\d+))?(?P<float2>[fFlL]*)|(?P<oct>0*)(?P<n0>\d+)(?P<qual2>[uUlL]*)""",r'L?"([^"\\]|\\.)*"',r'[a-zA-Z_]\w*',r'%:%:|<<=|>>=|\.\.\.|<<|<%|<:|<=|>>|>=|\+\+|\+=|--|->|-=|\*=|/=|%:|%=|%>|==|&&|&=|\|\||\|=|\^=|:>|!=|##|[\(\)\{\}\[\]<>\?\|\^\*\+&=:!#;,%/\-\?\~\.]',]
34 re_clexer=re.compile('|'.join(["(?P<%s>%s)"%(name,part)for name,part in zip(tok_types,exp_types)]),re.M)
35 accepted='a'
36 ignored='i'
37 undefined='u'
38 skipped='s'
39 def repl(m):
40         s=m.group(0)
41         if s.startswith('/'):
42                 return' '
43         return s
44 def filter_comments(filename):
45         code=Utils.readf(filename)
46         if use_trigraphs:
47                 for(a,b)in trig_def:code=code.split(a).join(b)
48         code=re_nl.sub('',code)
49         code=re_cpp.sub(repl,code)
50         return[(m.group(2),m.group(3))for m in re.finditer(re_lines,code)]
51 prec={}
52 ops=['* / %','+ -','<< >>','< <= >= >','== !=','& | ^','&& ||',',']
53 for x in range(len(ops)):
54         syms=ops[x]
55         for u in syms.split():
56                 prec[u]=x
57 def trimquotes(s):
58         if not s:return''
59         s=s.rstrip()
60         if s[0]=="'"and s[-1]=="'":return s[1:-1]
61         return s
62 def reduce_nums(val_1,val_2,val_op):
63         try:a=0+val_1
64         except TypeError:a=int(val_1)
65         try:b=0+val_2
66         except TypeError:b=int(val_2)
67         d=val_op
68         if d=='%':c=a%b
69         elif d=='+':c=a+b
70         elif d=='-':c=a-b
71         elif d=='*':c=a*b
72         elif d=='/':c=a/b
73         elif d=='^':c=a^b
74         elif d=='|':c=a|b
75         elif d=='||':c=int(a or b)
76         elif d=='&':c=a&b
77         elif d=='&&':c=int(a and b)
78         elif d=='==':c=int(a==b)
79         elif d=='!=':c=int(a!=b)
80         elif d=='<=':c=int(a<=b)
81         elif d=='<':c=int(a<b)
82         elif d=='>':c=int(a>b)
83         elif d=='>=':c=int(a>=b)
84         elif d=='^':c=int(a^b)
85         elif d=='<<':c=a<<b
86         elif d=='>>':c=a>>b
87         else:c=0
88         return c
89 def get_num(lst):
90         if not lst:raise PreprocError("empty list for get_num")
91         (p,v)=lst[0]
92         if p==OP:
93                 if v=='(':
94                         count_par=1
95                         i=1
96                         while i<len(lst):
97                                 (p,v)=lst[i]
98                                 if p==OP:
99                                         if v==')':
100                                                 count_par-=1
101                                                 if count_par==0:
102                                                         break
103                                         elif v=='(':
104                                                 count_par+=1
105                                 i+=1
106                         else:
107                                 raise PreprocError("rparen expected %r"%lst)
108                         (num,_)=get_term(lst[1:i])
109                         return(num,lst[i+1:])
110                 elif v=='+':
111                         return get_num(lst[1:])
112                 elif v=='-':
113                         num,lst=get_num(lst[1:])
114                         return(reduce_nums('-1',num,'*'),lst)
115                 elif v=='!':
116                         num,lst=get_num(lst[1:])
117                         return(int(not int(num)),lst)
118                 elif v=='~':
119                         num,lst=get_num(lst[1:])
120                         return(~int(num),lst)
121                 else:
122                         raise PreprocError("Invalid op token %r for get_num"%lst)
123         elif p==NUM:
124                 return v,lst[1:]
125         elif p==IDENT:
126                 return 0,lst[1:]
127         else:
128                 raise PreprocError("Invalid token %r for get_num"%lst)
129 def get_term(lst):
130         if not lst:raise PreprocError("empty list for get_term")
131         num,lst=get_num(lst)
132         if not lst:
133                 return(num,[])
134         (p,v)=lst[0]
135         if p==OP:
136                 if v==',':
137                         return get_term(lst[1:])
138                 elif v=='?':
139                         count_par=0
140                         i=1
141                         while i<len(lst):
142                                 (p,v)=lst[i]
143                                 if p==OP:
144                                         if v==')':
145                                                 count_par-=1
146                                         elif v=='(':
147                                                 count_par+=1
148                                         elif v==':':
149                                                 if count_par==0:
150                                                         break
151                                 i+=1
152                         else:
153                                 raise PreprocError("rparen expected %r"%lst)
154                         if int(num):
155                                 return get_term(lst[1:i])
156                         else:
157                                 return get_term(lst[i+1:])
158                 else:
159                         num2,lst=get_num(lst[1:])
160                         if not lst:
161                                 num2=reduce_nums(num,num2,v)
162                                 return get_term([(NUM,num2)]+lst)
163                         p2,v2=lst[0]
164                         if p2!=OP:
165                                 raise PreprocError("op expected %r"%lst)
166                         if prec[v2]>=prec[v]:
167                                 num2=reduce_nums(num,num2,v)
168                                 return get_term([(NUM,num2)]+lst)
169                         else:
170                                 num3,lst=get_num(lst[1:])
171                                 num3=reduce_nums(num2,num3,v2)
172                                 return get_term([(NUM,num),(p,v),(NUM,num3)]+lst)
173         raise PreprocError("cannot reduce %r"%lst)
174 def reduce_eval(lst):
175         num,lst=get_term(lst)
176         return(NUM,num)
177 def stringize(lst):
178         lst=[str(v2)for(p2,v2)in lst]
179         return"".join(lst)
180 def paste_tokens(t1,t2):
181         p1=None
182         if t1[0]==OP and t2[0]==OP:
183                 p1=OP
184         elif t1[0]==IDENT and(t2[0]==IDENT or t2[0]==NUM):
185                 p1=IDENT
186         elif t1[0]==NUM and t2[0]==NUM:
187                 p1=NUM
188         if not p1:
189                 raise PreprocError('tokens do not make a valid paste %r and %r'%(t1,t2))
190         return(p1,t1[1]+t2[1])
191 def reduce_tokens(lst,defs,ban=[]):
192         i=0
193         while i<len(lst):
194                 (p,v)=lst[i]
195                 if p==IDENT and v=="defined":
196                         del lst[i]
197                         if i<len(lst):
198                                 (p2,v2)=lst[i]
199                                 if p2==IDENT:
200                                         if v2 in defs:
201                                                 lst[i]=(NUM,1)
202                                         else:
203                                                 lst[i]=(NUM,0)
204                                 elif p2==OP and v2=='(':
205                                         del lst[i]
206                                         (p2,v2)=lst[i]
207                                         del lst[i]
208                                         if v2 in defs:
209                                                 lst[i]=(NUM,1)
210                                         else:
211                                                 lst[i]=(NUM,0)
212                                 else:
213                                         raise PreprocError("Invalid define expression %r"%lst)
214                 elif p==IDENT and v in defs:
215                         if isinstance(defs[v],str):
216                                 a,b=extract_macro(defs[v])
217                                 defs[v]=b
218                         macro_def=defs[v]
219                         to_add=macro_def[1]
220                         if isinstance(macro_def[0],list):
221                                 del lst[i]
222                                 accu=to_add[:]
223                                 reduce_tokens(accu,defs,ban+[v])
224                                 for x in range(len(accu)):
225                                         lst.insert(i,accu[x])
226                                         i+=1
227                         else:
228                                 args=[]
229                                 del lst[i]
230                                 if i>=len(lst):
231                                         raise PreprocError("expected '(' after %r (got nothing)"%v)
232                                 (p2,v2)=lst[i]
233                                 if p2!=OP or v2!='(':
234                                         raise PreprocError("expected '(' after %r"%v)
235                                 del lst[i]
236                                 one_param=[]
237                                 count_paren=0
238                                 while i<len(lst):
239                                         p2,v2=lst[i]
240                                         del lst[i]
241                                         if p2==OP and count_paren==0:
242                                                 if v2=='(':
243                                                         one_param.append((p2,v2))
244                                                         count_paren+=1
245                                                 elif v2==')':
246                                                         if one_param:args.append(one_param)
247                                                         break
248                                                 elif v2==',':
249                                                         if not one_param:raise PreprocError("empty param in funcall %s"%v)
250                                                         args.append(one_param)
251                                                         one_param=[]
252                                                 else:
253                                                         one_param.append((p2,v2))
254                                         else:
255                                                 one_param.append((p2,v2))
256                                                 if v2=='(':count_paren+=1
257                                                 elif v2==')':count_paren-=1
258                                 else:
259                                         raise PreprocError('malformed macro')
260                                 accu=[]
261                                 arg_table=macro_def[0]
262                                 j=0
263                                 while j<len(to_add):
264                                         (p2,v2)=to_add[j]
265                                         if p2==OP and v2=='#':
266                                                 if j+1<len(to_add)and to_add[j+1][0]==IDENT and to_add[j+1][1]in arg_table:
267                                                         toks=args[arg_table[to_add[j+1][1]]]
268                                                         accu.append((STR,stringize(toks)))
269                                                         j+=1
270                                                 else:
271                                                         accu.append((p2,v2))
272                                         elif p2==OP and v2=='##':
273                                                 if accu and j+1<len(to_add):
274                                                         t1=accu[-1]
275                                                         if to_add[j+1][0]==IDENT and to_add[j+1][1]in arg_table:
276                                                                 toks=args[arg_table[to_add[j+1][1]]]
277                                                                 if toks:
278                                                                         accu[-1]=paste_tokens(t1,toks[0])
279                                                                         accu.extend(toks[1:])
280                                                                 else:
281                                                                         accu.append((p2,v2))
282                                                                         accu.extend(toks)
283                                                         elif to_add[j+1][0]==IDENT and to_add[j+1][1]=='__VA_ARGS__':
284                                                                 va_toks=[]
285                                                                 st=len(macro_def[0])
286                                                                 pt=len(args)
287                                                                 for x in args[pt-st+1:]:
288                                                                         va_toks.extend(x)
289                                                                         va_toks.append((OP,','))
290                                                                 if va_toks:va_toks.pop()
291                                                                 if len(accu)>1:
292                                                                         (p3,v3)=accu[-1]
293                                                                         (p4,v4)=accu[-2]
294                                                                         if v3=='##':
295                                                                                 accu.pop()
296                                                                                 if v4==','and pt<st:
297                                                                                         accu.pop()
298                                                                 accu+=va_toks
299                                                         else:
300                                                                 accu[-1]=paste_tokens(t1,to_add[j+1])
301                                                         j+=1
302                                                 else:
303                                                         accu.append((p2,v2))
304                                         elif p2==IDENT and v2 in arg_table:
305                                                 toks=args[arg_table[v2]]
306                                                 reduce_tokens(toks,defs,ban+[v])
307                                                 accu.extend(toks)
308                                         else:
309                                                 accu.append((p2,v2))
310                                         j+=1
311                                 reduce_tokens(accu,defs,ban+[v])
312                                 for x in range(len(accu)-1,-1,-1):
313                                         lst.insert(i,accu[x])
314                 i+=1
315 def eval_macro(lst,defs):
316         reduce_tokens(lst,defs,[])
317         if not lst:raise PreprocError("missing tokens to evaluate")
318         (p,v)=reduce_eval(lst)
319         return int(v)!=0
320 def extract_macro(txt):
321         t=tokenize(txt)
322         if re_fun.search(txt):
323                 p,name=t[0]
324                 p,v=t[1]
325                 if p!=OP:raise PreprocError("expected open parenthesis")
326                 i=1
327                 pindex=0
328                 params={}
329                 prev='('
330                 while 1:
331                         i+=1
332                         p,v=t[i]
333                         if prev=='(':
334                                 if p==IDENT:
335                                         params[v]=pindex
336                                         pindex+=1
337                                         prev=p
338                                 elif p==OP and v==')':
339                                         break
340                                 else:
341                                         raise PreprocError("unexpected token (3)")
342                         elif prev==IDENT:
343                                 if p==OP and v==',':
344                                         prev=v
345                                 elif p==OP and v==')':
346                                         break
347                                 else:
348                                         raise PreprocError("comma or ... expected")
349                         elif prev==',':
350                                 if p==IDENT:
351                                         params[v]=pindex
352                                         pindex+=1
353                                         prev=p
354                                 elif p==OP and v=='...':
355                                         raise PreprocError("not implemented (1)")
356                                 else:
357                                         raise PreprocError("comma or ... expected (2)")
358                         elif prev=='...':
359                                 raise PreprocError("not implemented (2)")
360                         else:
361                                 raise PreprocError("unexpected else")
362                 return(name,[params,t[i+1:]])
363         else:
364                 (p,v)=t[0]
365                 if len(t)>1:
366                         return(v,[[],t[1:]])
367                 else:
368                         return(v,[[],[('T','')]])
369 re_include=re.compile('^\s*(<(?P<a>.*)>|"(?P<b>.*)")')
370 def extract_include(txt,defs):
371         m=re_include.search(txt)
372         if m:
373                 if m.group('a'):return'<',m.group('a')
374                 if m.group('b'):return'"',m.group('b')
375         toks=tokenize(txt)
376         reduce_tokens(toks,defs,['waf_include'])
377         if not toks:
378                 raise PreprocError("could not parse include %s"%txt)
379         if len(toks)==1:
380                 if toks[0][0]==STR:
381                         return'"',toks[0][1]
382         else:
383                 if toks[0][1]=='<'and toks[-1][1]=='>':
384                         return stringize(toks).lstrip('<').rstrip('>')
385         raise PreprocError("could not parse include %s."%txt)
386 def parse_char(txt):
387         if not txt:raise PreprocError("attempted to parse a null char")
388         if txt[0]!='\\':
389                 return ord(txt)
390         c=txt[1]
391         if c=='x':
392                 if len(txt)==4 and txt[3]in string.hexdigits:return int(txt[2:],16)
393                 return int(txt[2:],16)
394         elif c.isdigit():
395                 if c=='0'and len(txt)==2:return 0
396                 for i in 3,2,1:
397                         if len(txt)>i and txt[1:1+i].isdigit():
398                                 return(1+i,int(txt[1:1+i],8))
399         else:
400                 try:return chr_esc[c]
401                 except KeyError:raise PreprocError("could not parse char literal '%s'"%txt)
402 def tokenize(s):
403         return tokenize_private(s)[:]
404 @Utils.run_once
405 def tokenize_private(s):
406         ret=[]
407         for match in re_clexer.finditer(s):
408                 m=match.group
409                 for name in tok_types:
410                         v=m(name)
411                         if v:
412                                 if name==IDENT:
413                                         try:v=g_optrans[v];name=OP
414                                         except KeyError:
415                                                 if v.lower()=="true":
416                                                         v=1
417                                                         name=NUM
418                                                 elif v.lower()=="false":
419                                                         v=0
420                                                         name=NUM
421                                 elif name==NUM:
422                                         if m('oct'):v=int(v,8)
423                                         elif m('hex'):v=int(m('hex'),16)
424                                         elif m('n0'):v=m('n0')
425                                         else:
426                                                 v=m('char')
427                                                 if v:v=parse_char(v)
428                                                 else:v=m('n2')or m('n4')
429                                 elif name==OP:
430                                         if v=='%:':v='#'
431                                         elif v=='%:%:':v='##'
432                                 elif name==STR:
433                                         v=v[1:-1]
434                                 ret.append((name,v))
435                                 break
436         return ret
437 @Utils.run_once
438 def define_name(line):
439         return re_mac.match(line).group(0)
440 class c_parser(object):
441         def __init__(self,nodepaths=None,defines=None):
442                 self.lines=[]
443                 if defines is None:
444                         self.defs={}
445                 else:
446                         self.defs=dict(defines)
447                 self.state=[]
448                 self.count_files=0
449                 self.currentnode_stack=[]
450                 self.nodepaths=nodepaths or[]
451                 self.nodes=[]
452                 self.names=[]
453                 self.curfile=''
454                 self.ban_includes=set([])
455         def cached_find_resource(self,node,filename):
456                 try:
457                         nd=node.ctx.cache_nd
458                 except AttributeError:
459                         nd=node.ctx.cache_nd={}
460                 tup=(node,filename)
461                 try:
462                         return nd[tup]
463                 except KeyError:
464                         ret=node.find_resource(filename)
465                         if ret:
466                                 if getattr(ret,'children',None):
467                                         ret=None
468                                 elif ret.is_child_of(node.ctx.bldnode):
469                                         tmp=node.ctx.srcnode.search_node(ret.path_from(node.ctx.bldnode))
470                                         if tmp and getattr(tmp,'children',None):
471                                                 ret=None
472                         nd[tup]=ret
473                         return ret
474         def tryfind(self,filename):
475                 self.curfile=filename
476                 found=self.cached_find_resource(self.currentnode_stack[-1],filename)
477                 for n in self.nodepaths:
478                         if found:
479                                 break
480                         found=self.cached_find_resource(n,filename)
481                 if found and not found in self.ban_includes:
482                         self.nodes.append(found)
483                         if filename[-4:]!='.moc':
484                                 self.addlines(found)
485                 else:
486                         if not filename in self.names:
487                                 self.names.append(filename)
488                 return found
489         def addlines(self,node):
490                 self.currentnode_stack.append(node.parent)
491                 filepath=node.abspath()
492                 self.count_files+=1
493                 if self.count_files>recursion_limit:
494                         raise PreprocError("recursion limit exceeded")
495                 pc=self.parse_cache
496                 debug('preproc: reading file %r',filepath)
497                 try:
498                         lns=pc[filepath]
499                 except KeyError:
500                         pass
501                 else:
502                         self.lines.extend(lns)
503                         return
504                 try:
505                         lines=filter_comments(filepath)
506                         lines.append((POPFILE,''))
507                         lines.reverse()
508                         pc[filepath]=lines
509                         self.lines.extend(lines)
510                 except IOError:
511                         raise PreprocError("could not read the file %s"%filepath)
512                 except Exception:
513                         if Logs.verbose>0:
514                                 error("parsing %s failed"%filepath)
515                                 traceback.print_exc()
516         def start(self,node,env):
517                 debug('preproc: scanning %s (in %s)',node.name,node.parent.name)
518                 bld=node.ctx
519                 try:
520                         self.parse_cache=bld.parse_cache
521                 except AttributeError:
522                         bld.parse_cache={}
523                         self.parse_cache=bld.parse_cache
524                 self.current_file=node
525                 self.addlines(node)
526                 if env['DEFINES']:
527                         try:
528                                 lst=['%s %s'%(x[0],trimquotes('='.join(x[1:])))for x in[y.split('=')for y in env['DEFINES']]]
529                                 lst.reverse()
530                                 self.lines.extend([('define',x)for x in lst])
531                         except AttributeError:
532                                 pass
533                 while self.lines:
534                         (token,line)=self.lines.pop()
535                         if token==POPFILE:
536                                 self.count_files-=1
537                                 self.currentnode_stack.pop()
538                                 continue
539                         try:
540                                 ve=Logs.verbose
541                                 if ve:debug('preproc: line is %s - %s state is %s',token,line,self.state)
542                                 state=self.state
543                                 if token[:2]=='if':
544                                         state.append(undefined)
545                                 elif token=='endif':
546                                         state.pop()
547                                 if token[0]!='e':
548                                         if skipped in self.state or ignored in self.state:
549                                                 continue
550                                 if token=='if':
551                                         ret=eval_macro(tokenize(line),self.defs)
552                                         if ret:state[-1]=accepted
553                                         else:state[-1]=ignored
554                                 elif token=='ifdef':
555                                         m=re_mac.match(line)
556                                         if m and m.group(0)in self.defs:state[-1]=accepted
557                                         else:state[-1]=ignored
558                                 elif token=='ifndef':
559                                         m=re_mac.match(line)
560                                         if m and m.group(0)in self.defs:state[-1]=ignored
561                                         else:state[-1]=accepted
562                                 elif token=='include'or token=='import':
563                                         (kind,inc)=extract_include(line,self.defs)
564                                         if ve:debug('preproc: include found %s    (%s) ',inc,kind)
565                                         if kind=='"'or not strict_quotes:
566                                                 self.current_file=self.tryfind(inc)
567                                                 if token=='import':
568                                                         self.ban_includes.add(self.current_file)
569                                 elif token=='elif':
570                                         if state[-1]==accepted:
571                                                 state[-1]=skipped
572                                         elif state[-1]==ignored:
573                                                 if eval_macro(tokenize(line),self.defs):
574                                                         state[-1]=accepted
575                                 elif token=='else':
576                                         if state[-1]==accepted:state[-1]=skipped
577                                         elif state[-1]==ignored:state[-1]=accepted
578                                 elif token=='define':
579                                         try:
580                                                 self.defs[define_name(line)]=line
581                                         except Exception:
582                                                 raise PreprocError("Invalid define line %s"%line)
583                                 elif token=='undef':
584                                         m=re_mac.match(line)
585                                         if m and m.group(0)in self.defs:
586                                                 self.defs.__delitem__(m.group(0))
587                                 elif token=='pragma':
588                                         if re_pragma_once.match(line.lower()):
589                                                 self.ban_includes.add(self.current_file)
590                         except Exception ,e:
591                                 if Logs.verbose:
592                                         debug('preproc: line parsing failed (%s): %s %s',e,line,Utils.ex_stack())
593 def scan(task):
594         global go_absolute
595         try:
596                 incn=task.generator.includes_nodes
597         except AttributeError:
598                 raise Errors.WafError('%r is missing a feature such as "c", "cxx" or "includes": '%task.generator)
599         if go_absolute:
600                 nodepaths=incn+[task.generator.bld.root.find_dir(x)for x in standard_includes]
601         else:
602                 nodepaths=[x for x in incn if x.is_child_of(x.ctx.srcnode)or x.is_child_of(x.ctx.bldnode)]
603         tmp=c_parser(nodepaths)
604         tmp.start(task.inputs[0],task.env)
605         if Logs.verbose:
606                 debug('deps: deps for %r: %r; unresolved %r'%(task.inputs,tmp.nodes,tmp.names))
607         return(tmp.nodes,tmp.names)