[1] | 1 | #!/usr/bin/env python |
---|
| 2 | # ------------------------------------------------------------------------------------------------- |
---|
| 3 | # Macroprocessor vith PYthon script inclusion |
---|
| 4 | # |
---|
| 5 | # Written by Franck Wajsburt at LIP6 2009 |
---|
| 6 | # |
---|
| 7 | # This program is free software; you can redistribute it and/or |
---|
| 8 | # modify it under the terms of the GNU General Public License as |
---|
| 9 | # published by the Free Software Foundation; either version 2 of the |
---|
| 10 | # License, or (at your option) any later version. |
---|
| 11 | # |
---|
| 12 | # This program is distributed in the hope that it will be useful, but |
---|
| 13 | # WITHOUT ANY WARRANTY; without even the implied warranty of |
---|
| 14 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
---|
| 15 | # General Public License for more details. |
---|
| 16 | # |
---|
| 17 | # You should have received a copy of the GNU General Public License |
---|
| 18 | # along with this program; if not, write to the Free Software |
---|
| 19 | # Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. |
---|
| 20 | # ------------------------------------------------------------------------------------------------- |
---|
| 21 | # requires doctutils package to run rst2html |
---|
| 22 | # |
---|
| 23 | # TODO exectution step by step |
---|
| 24 | # TODO ecrire un manuel |
---|
| 25 | # TODO faire des tests unitaires |
---|
| 26 | # ------------------------------------------------------------------------------------------------- |
---|
| 27 | _date = '2009-12-30 16:00' |
---|
| 28 | _version = '1.07' |
---|
| 29 | _authors = 'Franck Wajsburt' |
---|
| 30 | _organization = '(UPMC/LIP6/SOC)' |
---|
| 31 | __doc__ = '''\ |
---|
| 32 | =========================================================================== |
---|
| 33 | Macroprocessor vith PYthon script inclusion |
---|
| 34 | - Authors: '''+_authors+''' |
---|
| 35 | - Date: '''+_date+''' |
---|
| 36 | - Version: '''+_version+''' |
---|
| 37 | - Organisation: '''+_organization+''' |
---|
| 38 | ===========================================================================''' |
---|
| 39 | |
---|
| 40 | import os, sys, pdb |
---|
| 41 | from optparse import OptionParser |
---|
| 42 | from datetime import datetime |
---|
| 43 | |
---|
| 44 | # ------------------------------------------------------------------------------------------------- |
---|
| 45 | # os and log utilities |
---|
| 46 | # ------------------------------------------------------------------------------------------------- |
---|
| 47 | |
---|
| 48 | def _mpyhash(s): |
---|
| 49 | return "%08x" % (hash(s) & 0xffffffff) |
---|
| 50 | |
---|
| 51 | def _exit(error): |
---|
| 52 | if (error <> ''): |
---|
| 53 | print >> sys.stderr, "\n*** mpy:", error |
---|
| 54 | print >> sys.stderr, "*** preprocessing aborted\n" |
---|
| 55 | exit(1) |
---|
| 56 | |
---|
| 57 | def _mpyfindfile(fname, mpyidir): |
---|
| 58 | "try to find fname in any directory (or subdir) of mpyidir list" |
---|
| 59 | "if fname is 'stdin' then just returns 'stdin' else returns real filename" |
---|
| 60 | "if fname does not exist then returns ''" |
---|
| 61 | if fname == 'stdin': |
---|
| 62 | return fname |
---|
| 63 | else: |
---|
| 64 | for path in mpyidir: |
---|
| 65 | for root, dirs, files in os.walk(path): |
---|
| 66 | for f in files: |
---|
| 67 | if f == fname: # fname found |
---|
| 68 | return os.path.join(root,f) |
---|
| 69 | return '' |
---|
| 70 | |
---|
| 71 | def _mpyopen(fname = '', mpyidir = [], realfname = ''): |
---|
| 72 | "two behaviors:" |
---|
| 73 | " 1. try to open realfname but if realfname is '' then 2." |
---|
| 74 | " 2. try to open fname in any directory OR SUBDIR of mpyidir list1" |
---|
| 75 | "returns tuple (string_with_file_content, real_file_name)" |
---|
| 76 | "if fname is 'stdin' then open sys.stdin file" |
---|
| 77 | if realfname == '': |
---|
| 78 | realfname = _mpyfindfile(fname,mpyidir) |
---|
| 79 | if realfname == '': |
---|
| 80 | _exit("unable to find file %s" % fname) |
---|
| 81 | if realfname == 'stdin': |
---|
| 82 | return sys.stdin, fname |
---|
| 83 | else: |
---|
| 84 | try: mpyin = open(realfname,'r') |
---|
| 85 | except IOError, e: _exit(e) # but cannot be open |
---|
| 86 | return mpyin, realfname |
---|
| 87 | |
---|
| 88 | def _mpytree(mess): |
---|
| 89 | print >> mpyglobals['mpytree'], mess |
---|
| 90 | mpyglobals['mpytree'].flush() |
---|
| 91 | |
---|
| 92 | def _mpylog(mess): |
---|
| 93 | global mpyglobals |
---|
| 94 | print >> mpyglobals['mpylog'], mess |
---|
| 95 | mpyglobals['mpylog'].flush() |
---|
| 96 | if mpyglobals['mpyverbose']: |
---|
| 97 | print >> sys.stderr, mess |
---|
| 98 | |
---|
| 99 | def _dictlog(dic, exclude=[]): |
---|
| 100 | for key,val in dic.items(): |
---|
| 101 | for exc in exclude: |
---|
| 102 | if key[0:len(exc)] == exc: |
---|
| 103 | break |
---|
| 104 | else: |
---|
| 105 | _mpylog(' :%s: %s' % (key, str(val))) |
---|
| 106 | |
---|
| 107 | # ------------------------------------------------------------------------------------------------- |
---|
| 108 | # macro expander |
---|
| 109 | # ------------------------------------------------------------------------------------------------- |
---|
| 110 | |
---|
| 111 | def _mpy( mpyins = [] # ['infile1', ...] |
---|
| 112 | , mpytxt = '' # 'python code' |
---|
| 113 | , mpyout = '' # 'outfile' |
---|
| 114 | , mpydict = {} ): # global dictionary |
---|
| 115 | |
---|
| 116 | # to allow _mpy call in inclusion |
---|
| 117 | exec 'from mpy import mpyglobals, mpygen, mpyexp' in mpydict |
---|
| 118 | |
---|
| 119 | # get arguments from the global dictionary |
---|
| 120 | global mpyglobals |
---|
| 121 | mpylog = mpyglobals['mpylog'] # log file |
---|
[2] | 122 | mpylist = mpyglobals['mpylist'] # file list log file |
---|
[1] | 123 | mpydebug = mpyglobals['mpydebug'] # True|False |
---|
| 124 | mpyverbose = mpyglobals['mpyverbose'] # True|False |
---|
| 125 | mpywdir = mpyglobals['mpywdir'] # working directory |
---|
| 126 | mpyidir = mpyglobals['mpyidir'] # list of input directory |
---|
| 127 | mpyoutlist = mpyglobals['mpyoutlist'] # list of opened output |
---|
| 128 | mpytabwidth= mpyglobals['mpytabwidth']# number of char of a tabulation character |
---|
| 129 | |
---|
| 130 | # this is necessary in order to write in mpyout file with just print |
---|
| 131 | if mpyout not in ('', 'stdout'): |
---|
| 132 | stdout = sys.stdout |
---|
| 133 | try: |
---|
| 134 | sys.stdout = open( mpywdir+'/'+mpyout, "w") |
---|
| 135 | mpyoutlist.append(mpywdir+'/'+mpyout) |
---|
[2] | 136 | mpylist.write(mpywdir+'/'+mpyout+'\n') |
---|
[1] | 137 | except IOError, e: _exit(e) |
---|
| 138 | |
---|
| 139 | opened_mpyin = [] # list of opened mpyin (include) |
---|
| 140 | |
---|
| 141 | # default values, a way to define the variable type |
---|
| 142 | mpyin = sys.stdin # mpyin file |
---|
| 143 | mpyfname = '' # real filename of mpyin file |
---|
| 144 | mpylineno = 1 # line number in mpyin file |
---|
| 145 | mpycharno = 0 # character number in mpyin file |
---|
| 146 | mpylength = 0 # number of character of mpyin file |
---|
| 147 | level = 0; # level > 0 in python inclusion |
---|
| 148 | mode = '' # '' outside python section, 'eval' | 'code' inside |
---|
| 149 | buf = '' # buffer for python section |
---|
| 150 | |
---|
| 151 | # the first item in mpyins is a buffer to exec |
---|
| 152 | mpyins = [mpytxt] + mpyins |
---|
| 153 | |
---|
| 154 | # for all files in mpyins list (first name is a buffer) { |
---|
| 155 | nbloop = 0 |
---|
| 156 | for fname in mpyins: |
---|
| 157 | |
---|
| 158 | if nbloop == 0: |
---|
| 159 | # the fist item of mpyins is a buffer |
---|
| 160 | mpyin, mpyfname = None, 'buffer' |
---|
| 161 | mpybuf = fname |
---|
| 162 | if mpybuf != '': |
---|
| 163 | lbuf = len(mpybuf) |
---|
| 164 | if lbuf > 31: lbuf = 31 |
---|
| 165 | if mpydebug == True: |
---|
| 166 | _mpylog("\n**Expand to file** %s **from text** `%s...`" |
---|
| 167 | % (mpyoutlist[-1], mpybuf[0:lbuf])) |
---|
| 168 | if mpydebug == True: |
---|
| 169 | _dictlog(mpydict, exclude=['_','mpy']) |
---|
| 170 | else: |
---|
| 171 | # try to open fnam then initialize all associated counters |
---|
| 172 | mpyin, mpyfname = _mpyopen(fname,mpyidir) |
---|
| 173 | mpybuf = mpyin.read(-1) # all chars of mpyin file |
---|
| 174 | if __name__ == '__main__': |
---|
| 175 | _mpylog('\nLog\n'+'-'*40) |
---|
| 176 | |
---|
| 177 | _mpylog("\n**Generate to file** %s **from file** %s" |
---|
| 178 | % (mpyoutlist[-1], mpyfname)) |
---|
| 179 | if nbloop == 1 and mpytxt == '': |
---|
| 180 | _dictlog(mpydict, exclude=['_','mpy']) |
---|
| 181 | |
---|
| 182 | mpylineno = 1 # line number in mpyin file |
---|
| 183 | mpycharno = 0 # character number in mpyin file |
---|
| 184 | mpylinecharno = 0 # character number in current line |
---|
| 185 | startlineno = 0 # first ligne of python inclusion |
---|
| 186 | mpylength = len(mpybuf) # number of character of mpyin file |
---|
| 187 | level = 0; # level > 0 in python inclusion |
---|
| 188 | mode = '' # '' because outside python section at first |
---|
| 189 | buf = '' # buffer for python section |
---|
| 190 | instr = 0 # in string boolean (0 outside, 1 inside) |
---|
| 191 | erasespace = 0 # nb space to erase for current line |
---|
| 192 | nbspacetab = 0 # nb space to erase for current expands |
---|
| 193 | |
---|
| 194 | # fname may include files, when a file ends, it is maybe an |
---|
| 195 | # include file and then we must continue to process. |
---|
| 196 | # This while exits with a break statement |
---|
| 197 | # while the hierarchical file continues { |
---|
| 198 | while True: |
---|
| 199 | |
---|
| 200 | # foreach char in current mpybuf { |
---|
| 201 | while mpycharno < mpylength: |
---|
| 202 | |
---|
| 203 | # get the current char |
---|
| 204 | c = mpybuf[mpycharno] |
---|
| 205 | mpycharno += 1 |
---|
| 206 | |
---|
| 207 | # in order to get line number of error |
---|
| 208 | if c == '\n': |
---|
| 209 | mpylinecharno = 0 |
---|
| 210 | mpylineno += 1 |
---|
| 211 | else: |
---|
| 212 | mpylinecharno += 1 |
---|
| 213 | |
---|
| 214 | # debug mode merges python section with result file |
---|
| 215 | if mpydebug == True : |
---|
| 216 | sys.stdout.write(c) |
---|
| 217 | |
---|
| 218 | # outside python section |
---|
| 219 | if level == 0: |
---|
| 220 | startlineno = mpylineno |
---|
| 221 | if c == '[': |
---|
| 222 | level += 1 |
---|
| 223 | mode = 'eval' |
---|
| 224 | elif c == '{': |
---|
| 225 | level += 1 |
---|
| 226 | mode = 'code' |
---|
| 227 | else: |
---|
| 228 | if mpydebug == False: # in debug mode c is already written |
---|
| 229 | sys.stdout.write(c) |
---|
| 230 | |
---|
| 231 | # inside python section |
---|
| 232 | else: |
---|
| 233 | |
---|
| 234 | # tabulation of expansion |
---|
| 235 | if erasespace != 0: |
---|
| 236 | if c == ' ' : |
---|
| 237 | erasespace -= 1 |
---|
| 238 | continue |
---|
| 239 | if c == '\t' : |
---|
| 240 | erasespace -= mpytabwidth |
---|
| 241 | continue |
---|
| 242 | else: |
---|
| 243 | if c == '\n': |
---|
| 244 | erasespace = nbspacetab |
---|
| 245 | buf += c |
---|
| 246 | continue |
---|
| 247 | else: |
---|
| 248 | _exit ( "%s[%d]: %d spaces expected not %c" |
---|
| 249 | % (mpyfname, mpylineno, nbspacetab, c)) |
---|
| 250 | |
---|
| 251 | # we are inside a string is it a newline ? |
---|
| 252 | if instr == 1 and c == '\n': |
---|
| 253 | erasespace = nbspacetab |
---|
| 254 | |
---|
| 255 | # is it a string delimitor ? |
---|
| 256 | if buf[-2:]+c == "'''" : |
---|
| 257 | instr = 1 - instr |
---|
| 258 | if instr == 1: |
---|
| 259 | nbspacetab = mpylinecharno-3 |
---|
| 260 | |
---|
| 261 | # count [ and { |
---|
| 262 | if c == '[' : |
---|
| 263 | if mode == 'eval': |
---|
| 264 | level += 1 |
---|
| 265 | buf += c |
---|
| 266 | elif c == '{': |
---|
| 267 | if mode == 'code': |
---|
| 268 | level += 1 |
---|
| 269 | buf += c |
---|
| 270 | |
---|
| 271 | # test for evaluation |
---|
| 272 | elif c == ']': |
---|
| 273 | if level == 0: |
---|
| 274 | if startlineno == mpylineno: |
---|
| 275 | _exit ( "%s[%d]: unexpected ']'" % (mpyfname, mpylineno)) |
---|
| 276 | else: |
---|
| 277 | _exit ( "%s[%d-%d]: unexpected ']'" % (mpyfname, startlineno, mpylineno)) |
---|
| 278 | elif mode == 'code': |
---|
| 279 | buf += c |
---|
| 280 | else: # mode eval |
---|
| 281 | level -= 1 |
---|
| 282 | if level != 0: |
---|
| 283 | buf += c |
---|
| 284 | else: |
---|
| 285 | # test if buf is a file name, if yes includes file |
---|
| 286 | # therefore pushes the current file and opens the new |
---|
| 287 | incname = _mpyfindfile(buf,mpyidir) |
---|
| 288 | if incname != '': |
---|
| 289 | if mpydebug == True: |
---|
| 290 | _mpylog("\nInclude to %s from %s" % (mpyout, incname)) |
---|
| 291 | |
---|
| 292 | # push known parameters of the current opened file |
---|
| 293 | opened_mpyin.append((mpyin, mpybuf, mpyfname, |
---|
| 294 | mpylineno, mpycharno, mpylength)) |
---|
| 295 | |
---|
| 296 | # old values required for test of recursivity just below |
---|
| 297 | oldmpyfname = mpyfname |
---|
| 298 | oldmpylineno = mpylineno |
---|
| 299 | |
---|
| 300 | # open the include file |
---|
| 301 | mpyin, mpyfname = _mpyopen(realfname = incname) |
---|
| 302 | mpybuf = mpyin.read(-1) |
---|
| 303 | mpylineno = 1 |
---|
| 304 | mpycharno = 0 |
---|
| 305 | mpylength = len(mpybuf) |
---|
| 306 | level = 0 |
---|
| 307 | buf = mode = '' |
---|
| 308 | |
---|
| 309 | # test recursive include |
---|
| 310 | for f in opened_mpyin[:-1]: |
---|
| 311 | if mpyfname in f: |
---|
| 312 | _exit ("%s[%d]: forbidden recursive inclusion on %s" |
---|
| 313 | % (oldmpyfname, oldmpylineno, mpyfname)) |
---|
| 314 | |
---|
| 315 | # just evaluate buf |
---|
| 316 | else: |
---|
| 317 | try: print eval(buf, mpydict), |
---|
| 318 | except Exception, e: |
---|
| 319 | if startlineno == mpylineno: |
---|
| 320 | _exit ( "%s[%d]: %s" % (mpyfname, mpylineno, e)) |
---|
| 321 | else: |
---|
| 322 | _exit ( "%s[%d-%d]: %s" % (mpyfname, startlineno, mpylineno, e)) |
---|
| 323 | buf = mode = '' |
---|
| 324 | |
---|
| 325 | # test for execute |
---|
| 326 | elif c == '}': |
---|
| 327 | |
---|
| 328 | if level == 0: |
---|
| 329 | if startlineno == mpylineno: |
---|
| 330 | _exit ( "%s[%d]: unexpected '}'" % (mpyfname, mpylineno)) |
---|
| 331 | else: |
---|
| 332 | _exit ( "%s[%d-%d]: unexpected '}'" % (mpyfname, startlineno, mpylineno)) |
---|
| 333 | elif mode == 'eval': |
---|
| 334 | buf += c |
---|
| 335 | else: # mode code |
---|
| 336 | level -= 1 |
---|
| 337 | if level != 0: |
---|
| 338 | buf += c |
---|
| 339 | else: |
---|
| 340 | try: |
---|
| 341 | mpydict |
---|
| 342 | # print >> sys.stderr, buf |
---|
| 343 | exec(buf, mpydict) |
---|
| 344 | # pdb.run(buf, mpydict) |
---|
| 345 | except Exception, e: |
---|
| 346 | if startlineno == mpylineno: |
---|
| 347 | _exit ( "%s[%d]: %s" |
---|
| 348 | % (mpyfname, mpylineno, e)) |
---|
| 349 | else: |
---|
| 350 | _exit ( "%s[%d-%d]: %s" |
---|
| 351 | % (mpyfname, startlineno, mpylineno, e)) |
---|
| 352 | buf = mode = '' |
---|
| 353 | else: |
---|
| 354 | buf += c |
---|
| 355 | |
---|
| 356 | # } end while mpycharno < mpylength: |
---|
| 357 | |
---|
| 358 | if mpyfname not in ['stdin', 'buffer']: |
---|
| 359 | mpyin.close() |
---|
| 360 | |
---|
| 361 | if level <> 0: |
---|
| 362 | if mode == 'eval': |
---|
| 363 | _exit ("%s[%d]: expected ']'" % (mpyfname,mpylineno)) |
---|
| 364 | else: |
---|
| 365 | _exit ("%s[%d]: expected '}'" % (mpyfname,mpylineno)) |
---|
| 366 | |
---|
| 367 | # pops included file if there is one, else breaks while |
---|
| 368 | try: |
---|
| 369 | mpyin, mpybuf, mpyfname, mpylineno, mpycharno, mpylength = opened_mpyin.pop() |
---|
| 370 | level = 0 |
---|
| 371 | buf = mode = '' |
---|
| 372 | |
---|
| 373 | except: break |
---|
| 374 | |
---|
| 375 | # } end while True: |
---|
| 376 | |
---|
| 377 | # because the first fname is actually a buffer |
---|
| 378 | nbloop += 1 |
---|
| 379 | |
---|
| 380 | # } end for fname in mpyins: |
---|
| 381 | |
---|
| 382 | # close and redirect sys.stdout |
---|
| 383 | if mpyout not in ('', 'stdout'): |
---|
| 384 | sys.stdout.close() |
---|
| 385 | sys.stdout = stdout |
---|
| 386 | mpyoutlist.pop() |
---|
| 387 | |
---|
| 388 | # ------------------------------------------------------------------------------------------------- |
---|
| 389 | |
---|
| 390 | def mpygen(mpyin, param): |
---|
| 391 | "call the macro processor on file mpyin with its own dictionaty, produce a newfile" |
---|
| 392 | global mpyglobals |
---|
| 393 | |
---|
| 394 | # check parameters |
---|
| 395 | if type(mpyin) <> str: |
---|
| 396 | _exit('first argument of mpygen: %s is not a valid filename' % str(mpyin)) |
---|
| 397 | if type(param) <> dict: |
---|
| 398 | _exit('second argument of mpygen: %s is not a valid dictionary' % str(param)) |
---|
| 399 | |
---|
| 400 | # test input filename syntax |
---|
| 401 | mpyout = os.path.basename(mpyin).split('.') |
---|
| 402 | if mpyout[-2] <> 'mpy': |
---|
| 403 | _exit('filename %s has not a valid form (anyroot.mpy.anyext)' % str(mpyin)) |
---|
| 404 | |
---|
| 405 | # generate output filename |
---|
| 406 | hashnumber = _mpyhash(`param`) |
---|
| 407 | mpyout_base = '.'.join(mpyout[0:-2]) |
---|
| 408 | mpyout = mpyout_base+'_'+hashnumber+'.'+mpyout[-1] |
---|
| 409 | mpymodelname = mpyout_base+'_'+hashnumber |
---|
| 410 | param['mpymodelname'] = mpymodelname |
---|
| 411 | |
---|
| 412 | # call the macro processor |
---|
| 413 | _mpytree('%s* %s <- %s\n' % (' '*mpyglobals['mpylevelgen'], mpyout, mpyin)) |
---|
| 414 | mpyglobals['mpylevelgen'] += 1 |
---|
| 415 | _mpy(mpyins = [mpyin], mpydict = param, mpyout = mpyout) |
---|
| 416 | mpyglobals['mpylevelgen'] -= 1 |
---|
| 417 | _mpytree('') |
---|
| 418 | |
---|
| 419 | # return the computed model name |
---|
| 420 | return mpymodelname |
---|
| 421 | |
---|
| 422 | # ------------------------------------------------------------------------------------------------- |
---|
| 423 | |
---|
| 424 | def mpyexp(txt, param): |
---|
| 425 | "call the macro processor on a buffer of chars with its own dictionary" |
---|
| 426 | if type(txt) <> str: |
---|
| 427 | _exit('argument of mpyexp: must be a string not %s' % type(txt)) |
---|
| 428 | _mpy(mpytxt = txt, mpydict = param) |
---|
| 429 | |
---|
| 430 | # ------------------------------------------------------------------------------------------------- |
---|
| 431 | # define globals dictionnary |
---|
| 432 | # ------------------------------------------------------------------------------------------------- |
---|
| 433 | |
---|
| 434 | _parser = OptionParser( |
---|
| 435 | usage = "%prog [options] [infiles...]", |
---|
| 436 | version = "version "+_version, |
---|
| 437 | description = "mpy opens all infiles list (default stdin) to macro-process " |
---|
| 438 | "them and writes the result in OFILE (default stdout). " |
---|
| 439 | "Infiles are searched in any dir or subdir of PATHS (default " |
---|
| 440 | "MPYIDIR environment variable)") |
---|
| 441 | |
---|
| 442 | _parser.set_defaults( verbose = False , debug = False , txt = '', tab = 8 |
---|
| 443 | , wdir = '.' , idir = '' , output = 'stdout') |
---|
| 444 | |
---|
| 445 | _parser.add_option("-v", "--verbose", action = "store_true", dest = "verbose" |
---|
| 446 | , help = "trace processing step") |
---|
| 447 | _parser.add_option("-d", "--debug", action = "store_true", dest = "debug" |
---|
| 448 | , help = "do not remove python inclusions") |
---|
| 449 | _parser.add_option("-t", "--txt", dest = "txt" |
---|
| 450 | , help = "text (chars) to macro process") |
---|
| 451 | _parser.add_option("-b", "--tab", dest = "tab" |
---|
| 452 | , help = "tabulation width [default: %default]") |
---|
| 453 | _parser.add_option("-w", "--wdir", dest = "wdir" |
---|
| 454 | , help = "define the working directory [default: %default]") |
---|
| 455 | _parser.add_option("-o", "--output", dest = "ofile", default = 'stdout' |
---|
| 456 | , help = "define output filename [default: %default] ") |
---|
[2] | 457 | _parser.add_option("-n", "--name", dest = "name", default = 'mpy' |
---|
| 458 | , help = "define instance name, basename for logs [default: 'mpy']") |
---|
[1] | 459 | _parser.add_option("-i", "--idir", dest = "idir" |
---|
| 460 | , help = "list of directories (separated with colon ':') " |
---|
| 461 | "where to find input files " |
---|
| 462 | "(default %prog use MPYPATH environment variable) " |
---|
| 463 | "%prog begins to search in the working directory (-w option) " |
---|
| 464 | "then in all the directories or subdirectories of the path") |
---|
| 465 | |
---|
| 466 | (_options, _mpyins) = _parser.parse_args() |
---|
| 467 | |
---|
| 468 | # if no path dirctories are given in command line, getenv MPYIDIR |
---|
| 469 | if _options.idir == '': |
---|
| 470 | try: _options.idir = os.environ['MPYPATH'] |
---|
| 471 | except: pass |
---|
| 472 | |
---|
| 473 | # gets the input files |
---|
| 474 | if len(_mpyins) == 0: |
---|
| 475 | _mpyins = ['stdin'] |
---|
| 476 | |
---|
| 477 | # open log file |
---|
| 478 | if not os.path.isdir(_options.wdir): |
---|
| 479 | _exit('%s is not a working directory' % _options.wdir) |
---|
| 480 | try: |
---|
[2] | 481 | _mpymetaname = os.path.join(_options.wdir,_options.name+"_meta.log") |
---|
| 482 | _mpytreename = os.path.join(_options.wdir,_options.name+"_tree.log") |
---|
| 483 | _mpylistname = os.path.join(_options.wdir,_options.name+".list") |
---|
[1] | 484 | _mpymetafile = open(_mpymetaname,"a") |
---|
| 485 | _mpytreefile = open(_mpytreename,"a") |
---|
[2] | 486 | _mpylistfile = open(_mpylistname,"a") |
---|
| 487 | _logname = os.path.join(_options.wdir, _options.name+".log") |
---|
| 488 | _htmlname = os.path.join(_options.wdir,_options.name+".html") |
---|
[1] | 489 | except IOError, e: |
---|
| 490 | _exit(e) |
---|
| 491 | |
---|
| 492 | mpyglobals = dict( mpyverbose = _options.verbose # True|False |
---|
| 493 | , mpydebug = _options.debug # True|False |
---|
| 494 | , mpywdir = _options.wdir # working directory |
---|
| 495 | , mpyidir = [_options.wdir]+_options.idir.split(':') # split pathes in a list |
---|
| 496 | , mpylevelgen = 1 # level of generation (tree deep) |
---|
| 497 | , mpylog = _mpymetafile |
---|
| 498 | , mpytree = _mpytreefile |
---|
[2] | 499 | , mpylist = _mpylistfile |
---|
[1] | 500 | , mpytabwidth = _options.tab |
---|
| 501 | , mpyoutlist = [_options.ofile]) |
---|
| 502 | |
---|
| 503 | # ------------------------------------------------------------------------------------------------- |
---|
| 504 | # main function |
---|
| 505 | # ------------------------------------------------------------------------------------------------- |
---|
| 506 | |
---|
| 507 | if __name__ == '__main__': |
---|
| 508 | _mpytree(''' |
---|
| 509 | ======================================================================== |
---|
| 510 | MPY: Macroprocessor with PYthon script inclusion (V'''+_version+''') |
---|
| 511 | ======================================================================== |
---|
| 512 | Generation date '''+datetime.now().strftime("%A, %d. %B %Y %I:%M%p")+''' |
---|
| 513 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
---|
| 514 | ''') |
---|
| 515 | _mpytree( '\nTree Generation\n'+'-'*40+'\n\n') |
---|
| 516 | _mpytree( '* %s <- %s\n' % (_options.ofile, _mpyins[0])) |
---|
| 517 | _mpy(mpytxt = _options.txt, mpyout = _options.ofile, mpyins = _mpyins, mpydict = {}) |
---|
| 518 | try: |
---|
| 519 | os.system('cat '+_mpytreename+' '+_mpymetaname+' > '+_logname) |
---|
| 520 | os.remove(_mpytreename) |
---|
| 521 | os.remove(_mpymetaname) |
---|
[2] | 522 | os.system('rst2html '+_logname+' '+_htmlname+' 2> /dev/null') |
---|
[1] | 523 | except: |
---|
| 524 | pass |
---|